Una aplicación de Xuda es un conjunto de documentos tipados, y un único intérprete los ejecuta.
Studio no genera una base de código que usted deba mantener. Un proyecto es un conjunto plano de documentos, todos ellos marcados con docType studio, en doce tipos de nodo: componentes, tablas, unidades de datos, rutas, agentes y los demás. El árbol del panel izquierdo se deriva de esos documentos al cargar, a partir de un puntero al padre en cada uno, y nunca se almacena como un árbol propio. Esos mismos documentos son los que una vista previa pide por id, los que recorre una compilación y los que ejecuta el runtime cuando alguien abre la aplicación. Nada intermedio los compila en otra cosa.

Tipos de nodo con los que se construye un proyecto
Tipos de evento a los que puede reaccionar un componente
Tipos de despliegue con los que puede publicarse el mismo proyecto
Plugins propios, repartidos en seis categorías
Cinco árboles separados, y ningún documento de árbol en ninguna parte.
El panel izquierdo no contiene un árbol. Contiene cinco, y un control segmentado de cinco iconos situado encima decide cuál se monta, de modo que tablas, pantallas, estado compartido, URLs y agentes son cinco espacios de direcciones separados y no cinco ramas del mismo. Ninguno de los cinco se almacena como árbol tampoco. Cada nodo es un documento que lleva un único puntero parentId y una clave de orden order_ts, y un web worker reconstruye toda la estructura al cargar, buscando los hijos nivel por nivel y admitiendo solo los documentos cuyo stat es 3. Mover un nodo hacia arriba o hacia abajo no es mover un archivo: guarda exactamente dos documentos con sus valores order_ts intercambiados. Eliminar un subárbol escribe stat 4 en todos sus documentos y los deja en el almacenamiento, y por eso el árbol deja de mostrarlos y el índice de búsqueda deja de indexarlos en el mismo instante. Abra un componente, cambie a su pestaña UI y aparecerá un segundo árbol debajo del primero, el árbol de elementos de ese componente, con un divisor arrastrable entre ambos cuya posición se recuerda.
Lo de las cuatro pestañas es cierto en un componente. Cualquier otro tipo abre otra cosa.
La versión de esta página que quizá usted leyó decía que pantallas, trabajos en segundo plano y endpoints de API son el mismo tipo de objeto con las mismas cuatro pestañas. La primera mitad es cierta, la segunda no. El editor construye su barra de pestañas según el tipo de nodo, y el envoltorio se encoge y se agranda: un componente obtiene cuatro pestañas, un batch o una unidad de datos obtiene tres y no tiene UI alguna, una unidad de API obtiene cuatro pero la cuarta es Output en lugar de UI, y cinco de los doce tipos abren una sola pestaña o ninguna: alert, javascript, route y ai_agent abren cada uno un editor, y una carpeta no abre nada. La barra solo se renderiza cuando un nodo tiene más de una pestaña, así que esos cinco llegan sin barra encima. Qué pestaña está abierta es un parámetro de consulta en la URL del editor, y la última pestaña que usted tenía en un nodo dado se recuerda por nodo, de modo que al volver queda donde lo dejó. La segunda columna es la otra mitad de la misma gramática. El panel Crear ofrece un conjunto distinto de tipos según el nodo sobre el que usted hizo clic derecho, y una carpeta simplemente hereda el conjunto de la sección en la que está.
Qué abre | Dónde se puede crear | |
|---|---|---|
| Componente | Datasource, Fields, Events, UI | Bajo Programs, o dentro de otro componente |
| API | Datasource, Fields, Events, Output | Bajo Programs o cualquier otra unidad, nunca dentro de un componente |
| Batch | Datasource, Fields, Events. Sin pestaña UI | Programs, dentro de un componente o dentro de cualquier otra unidad |
| Get data (get_data) | Datasource, Fields, Events. Sin pestaña UI | Programs, dentro de un componente o dentro de cualquier otra unidad |
| Set data (set_data) | Datasource, Fields, Events. Sin pestaña UI | Programs, dentro de un componente o dentro de cualquier otra unidad |
| Alert | Una pestaña, Alert | Bajo Programs o dentro de un componente, en ningún otro sitio |
| JavaScript | Una pestaña, Editor | Bajo Programs o dentro de un componente, en ningún otro sitio |
| Tabla | Data, Fields, Indexes | Bajo Database, donde Crear se deshabilita sobre la propia tabla |
| Globals | Fields, Events | No desde el árbol: la raíz Globals rechaza nuevos hijos |
| Route | Una pestaña, Route | Bajo Routes, el único tipo que ofrece esa sección |
| Agente de IA (ai_agent) | Una pestaña, AI Agent | Bajo AI Agents, el único tipo que ofrece esa sección |
| Carpeta | Nada en absoluto. Abrir una carpeta termina de inmediato | Bajo Programs o Database, o dentro de un componente o de cualquier otra unidad |
El asistente escribe en el mismo árbol que usted edita a mano, y hay un modo que no escribe nada.
Describa lo que quiere en el panel de IA de un proyecto abierto y el constructor propondrá tablas, componentes, campos y eventos como documentos normales dentro del árbol normal, y por eso usted puede abrir el resultado después y cambiar un solo campo. Los dos interruptores del panel no son el mismo interruptor: el alcance decide de qué trata la conversación, el modo decide si el turno puede escribir. Dentro de Studio el compositor además oculta el selector de modelo y el selector de agente que muestra el resto del panel de control, así que no hay modelo que elegir ni agente que elegir.
- El modo Plan no escribe nada. El panel describe Auto como una ejecución de principio a fin sin interrupciones y Plan como una investigación que propone un enfoque sin hacer cambios. La elección viaja en la petición como plan_mode, y el servidor la convierte en un método distinto con el guardado desactivado durante todo el turno.
- El alcance decide a qué queda ligado el turno. En alcance general la conversación hace referencia a la aplicación; en alcance de nodo hace referencia al nodo que usted tiene abierto, como studio_node y no como aplicación. Cambiar de alcance inicia un chat nuevo y recarga la lista de chats, porque los chats anteriores se recuperan según aquello a lo que hacen referencia.
- Los chips de contexto son interruptores, no etiquetas. Aparecen hasta tres: el programa abierto en el editor, un nodo distinto seleccionado en el árbol y el elemento de UI seleccionado mientras la pestaña UI está abierta. Desactive uno y queda fuera de la petición. Desactive los tres y el turno se envía sin contexto alguno.
- El constructor es un único paquete npm con métodos nombrados, y dos de esos métodos escriben plugins. app_builder guarda documentos de studio, app_planner no, y create_plugin_via_ai y modify_plugin_via_ai se exportan desde el mismo paquete. Lo que ese paquete hace por dentro no está en el código de la plataforma, así que esta página describe el punto de llamada y se detiene ahí.
- Usted lo describeEn el panel de IA de un proyecto abierto, en alcance general o ligado a un nodo
- Los chips fijan el contextoPrograma abierto, un nodo seleccionado en otro punto del árbol, el elemento de UI seleccionado
- Los últimos 12 mensajes viajan con la peticiónCada uno recortado a 2000 caracteres antes de enviarse
- app_builder guarda, app_planner noAceptar un plan lo reenvía con la instrucción de ejecutarlo de principio a fin
Un turno de construcción devuelve un comprobante que nombra lo que cambió.
La respuesta no es el modelo narrando lo que hizo. Un formateador de la plataforma lee el resultado estructurado y redacta el mensaje: cuenta los documentos, los agrupa por tipo de menú, enumera hasta doce por nombre con el id del documento entre corchetes e indica si se guardaron. Un turno de plan renderiza campos completamente distintos, un resumen, hasta doce unidades propuestas, ocho pasos de orden de construcción y ocho comprobaciones de aceptación, y siempre indica que mantuvo el turno en modo de planificación. Cuando el asistente necesita algo de usted para continuar, tampoco lo pide en prosa: emite un bloque de preguntas estructurado que el panel renderiza como un asistente por pasos, con dos o tres opciones por pregunta y una fila Otro de texto libre que añade la propia interfaz. Mientras el turno se ejecuta, el texto de estado rota por una lista fija de tres mensajes, una lista por modo, cambiando cada 1800 milisegundos.
Detrás de un único control segmentado hay dos motores.
En un datasource de tabla el modo de filtro es Index o Query, y cuando el ajuste está ausente el runtime infiere Index si hay un índice seleccionado y Query si no lo hay. No son dos apariencias sobre un mismo planificador. El modo Index lee una clave compuesta que la tabla ya escribió en cada registro. El modo Query lee un selector ensamblado en el momento de la petición. Lo que usted puede expresar, y lo que tiene garantizado, cambia con la posición de ese control.
No hay registro de propiedades. Cada propiedad es un atributo.
Seleccione un elemento en el árbol y el panel de propiedades se llenará de filas. Esas filas no escriben en un bloque de propiedades privado asociado al nodo. Un elemento es un id, un nombre de etiqueta, un mapa de atributos, hijos y contenido de texto, y cada ajuste del panel es literalmente un atributo del espacio de nombres xu-. Active Bind y el marcado gana xu-bind. Escriba lo que quiera en Añadir atributo y quedará junto a los demás como un atributo normal. Por eso una clase que usted escribió a mano, un atributo que usted inventó y un control del panel acaban en el mismo sitio, y por eso Editar HTML le muestra toda la verdad sobre un elemento y no una interpretación de ella.
- El panel se abre con tres filas, xu-show, xu-bind y xu-ref, y crece a medida que usted usa los acordeones de abajo. Otros quince nombres quedan fuera de la lista libre de atributos porque cada uno ya tiene su propio control dedicado, de modo que ningún atributo es editable en dos sitios a la vez.
- Show y Render no son dos palabras para ocultar, y el runtime lo dice en su propio comentario. xu-show es un interruptor de visualización y el elemento sigue montado. Una condición de render mete o saca un subárbol del documento, así que el elemento simplemente no está en el DOM.
- Cualquier atributo tiene un gemelo calculado: escriba xu-exp: delante del nombre, o pulse el botón fx junto al campo, y el valor pasa a ser una expresión que se recalcula cuando cambian sus dependencias. Es genérico y no una lista curada de propiedades enlazables, así que funciona sobre src, sobre un atributo que usted escribió hace un minuto y sobre campos declarados por un plugin. Un valor y su gemelo calculado son la misma ranura, no un valor por defecto más una anulación, así que Studio señala un elemento que lleve ambos y le ofrece eliminar el estático. Una excepción documentada: xu-exp:class sustituye al atributo class estático en lugar de fusionarse con él.
- El límite, dicho sin rodeos: no hay interfaz de estilos. Ni controles de espaciado, ni controles de tipografía, ni selector de color, ni editor del modelo de caja. El estilo es una fila de chips de clase más un editor de CSS en crudo, así que un valor de padding es una cadena de clases de Tailwind o de Ionic que usted escribe o pega, y una clase condicional es un nombre de clase asociado a una expresión dentro de xu-class.
El lienzo es una superficie de maquetación. El runtime está a un interruptor de distancia.
Ambas superficies leen el mismo árbol de elementos, y hacen cosas distintas con él. El lienzo de diseño renderiza su marcado para que usted pueda maquetar y seleccionar, pero no ejecuta su aplicación: los componentes anidados y los widgets se dibujan como marcadores de posición etiquetados, y las condiciones se comparan como texto en lugar de evaluarse. El interruptor de la barra de herramientas cambia el lienzo por la vista previa en vivo, que es el runtime real con un popover de Props para introducir valores de prueba. Saber sobre qué superficie está usted explica la mayoría de los momentos en que una pantalla se ve bien en un sitio y se comporta de otro modo en el otro.
Un flujo de trabajo es una cola de trabajos, no una lista de awaits.
Un evento no ejecuta sus acciones una tras otra. Recorre el flujo de trabajo una vez y añade un trabajo por cada paso habilitado a un único arreglo alojado en la sesión, y un bucle de vaciado independiente que se ejecuta cada milisegundo toma el primer trabajo que no esté ya marcado como ocupado y lo ejecuta. El orden es el orden del arreglo, de arriba abajo. Lo que inicia el paso siguiente no es que el paso anterior termine, sino que el paso anterior elimine su propio trabajo. La marca async es una línea dentro de ese bucle.
Veinticuatro acciones en nueve grupos, y el argumento que lee cada una.
El selector Añadir acción se construye a partir de un único archivo de catálogo, y fuera de las entradas de IA cada acción coincide en tres sitios: el catálogo, el mapa de manejadores del runtime y el registro de validación que anota la clave de payload que lee cada acción. Ese registro es la columna de la derecha. Dos cosas antes de la tabla. Invoke Action ofrece once valores en su desplegable y nueve funcionan, porque act_close y act_back están comentados tanto en el runtime como en la lista de permitidos del validador. Y siete acciones antiguas sobre elementos de UI se rechazan de plano por obsoletas, en lugar de tolerarse en silencio. También puede crear una acción sin el selector: arrastre un nodo del árbol hasta el flujo de trabajo y el tipo de nodo decide la acción, así que un nodo get data se convierte en Get Data y un componente en Call Page. Suéltelo sobre una fila que ya existe y redirige esa fila en lugar de añadir una nueva.
Las acciones del grupo | Qué lee la acción | |
|---|---|---|
| Navegación, 3 | Call Page, Call Modal, Call Popover | Cada una nombra el componente que se abrirá, y ese es todo el payload. |
| Base de datos, 3 | Get Data, Set Data, Batch | La unidad de datasource que se ejecutará. Set Data y Batch también nombran el campo donde aterriza su resultado. |
| JavaScript, 4 | Call Native JS, Call Evaluate JS, Execute Native JS, Execute Evaluate JS | Las dos acciones Call nombran una unidad de programa JavaScript del árbol. Las dos acciones Execute llevan el código en sí, escrito dentro de la acción. |
| Manejadores de eventos, 4 | Raise Event, Emit Event, Invoke Action, Delay | Raise Event nombra un evento y sus parámetros, cada uno un valor literal o una expresión. Invoke Action lee uno de los nueve valores permitidos. Delay lee un número de milisegundos. |
| Utilidades de UI, 4 | Call Alert, Alert, Loader On, Loader Off | Call Alert nombra una unidad de alerta. Alert lleva su propio modo de visualización, tipo, título y cuerpo. Las dos acciones de loader no leen nada. |
| API, 3 | Call Project API, Call System API, Call External API | Una API de proyecto nombra una unidad de su propio árbol, una API de sistema nombra un método, y una API externa toma una URL y un método HTTP. |
| Conjunto de datos, 1 | Update | Un solo valor, escrito como "@field: expression; @other: expression", o como un objeto JSON5. |
| Plugins, 1 | Call Library | El nombre del plugin y el método dentro de él, de modo que una biblioteca comprada se lee como cualquier otra acción de esta tabla. |
| Comentario, 1 | Comment | Nada. El registro la describe como documentación únicamente, y el manejador del runtime no hace más que eliminar su propio trabajo. |
La vía de escape es un camino, no una caja de texto.
Siete lugares le permiten dejar de configurar y empezar a escribir código, y el más profundo de ellos no es siquiera una acción: un programa JavaScript es su propia unidad en el árbol, con su propia salida de compilación y un conjunto documentado de cosas que se le entregan. Dos límites merecen mencionarse aquí mismo. El validador no analiza el cuerpo de un JavaScript, así que un error de sintaxis aparece desde la compilación como un fallo de compilado y no desde el verificador, que solo advierte cuando el script está vacío. Y un atributo script o style en línea sobre un elemento no puede contener ningún carácter de comilla.
- Al cuerpo de un programa se le entregan diez argumentos con nombre: params, xu, SESSION_ID, SESSION_OBJ, jobNoP, $container, func, glb, APP_OBJ y evt. Si no hay import ni export de nivel superior, se envuelve en una función async, de modo que await de nivel superior funciona.
- Escriba un import o un export y pasa a ser un módulo ES real. Los especificadores relativos se reescriben respecto de la carpeta scripts de ese programa, así que una unidad puede importar sus propios archivos hermanos.
- Guardar una unidad JavaScript dispara una compilación de Vite sin bloquear el guardado. En tiempo de ejecución el motor prefiere el módulo compilado, con cache busting por compilación, carga una hoja de estilos solo si el módulo exporta una, y como último recurso ejecuta el código fuente con el código de advertencia RUN_MSG_JS_010.
- El objeto xu que recibe un script es una API de quince métodos: leer y escribir un campo, invocar un evento, cuatro llamadas a la base de datos, llamar a otro script, tres tipos de llamada a API, alerta, log y leer o escribir en el drive. El código en línea tiene otra forma distinta: se envuelve como una función async y se llama con el elemento y el evento del navegador.
La vista previa es un par de su editor, y tiene permiso para darse por vencida con usted.
Una sesión de vista previa se abre en un canal con el nombre de su token de sesión y pide documentos a su pestaña abierta de uno en uno por id. Studio responde desde memoria con una copia del documento que hay en su pantalla, así que no hay ningún bundler en ese camino y un cambio guardado está en la sesión en ejecución de inmediato. También hay un plazo. Si su pestaña no ha respondido en cinco segundos, esa sesión pasa a la copia compilada del servidor y no vuelve a preguntarle en toda su vida.
La caja de comandos es eval, ejecutándose dentro de la página que usted está previsualizando.
No hay vocabulario de comandos que aprender, porque no hay conjunto de comandos. Lo que usted escribe se envía a la vista previa como una cadena, se evalúa allí, y el resultado vuelve y se renderiza como un árbol de dos niveles de profundidad. Todo lo que la página en ejecución puede ver, usted puede verlo: el objeto de sesión, los datasources, los ayudantes del runtime. Un error lanzado vuelve con una marca de error y se renderiza en rojo. Inspeccionar es la otra mitad: actívelo y todo elemento con un id de ui se resaltará bajo el cursor; al hacer clic en uno se devuelve el componente que lo contiene y el nodo dentro de él, con un botón que abre ese componente en su pestaña UI y selecciona el nodo en el árbol. Eso es ir de un píxel a un nodo en dos clics.
Un guardado es una escritura local. La versión la escribe otra cosa, después.
No hay guardado automático. Pulsar guardar entrega el documento a un worker, que lo sella y lo escribe en una base de datos dentro de su navegador, y eso es todo lo que hace su pulsación. Todo lo posterior es maquinaria distinta: una difusión a sus otras pestañas, la replicación hacia la base de datos de la aplicación y un proceso del servidor que observa esa base de datos, que es lo que realmente acuña una versión. El orden importa, porque le dice qué sobrevive a una caída de red y qué no.
La píldora tiene cuatro estados, y uno de ellos dice que su pestaña está desactualizada.
La etiqueta junto al editor es derivada, no almacenada: compara la revisión que usted guardó con la instantánea más reciente del servidor. Actual significa que existe una instantánea exacta de su revisión, o que la diferencia son solo metadatos de compilación. Registrando significa que su revisión va por delante y la captura todavía no ha aterrizado. Atrasada significa que su revisión guardada es más antigua que la instantánea más reciente, es decir, que esta sesión del navegador se durmió durante varias revisiones, y el popover lo dice en un aviso en lugar de afirmar que usted está al día. Desconocida significa misma generación, contenido distinto, lo que el código fuente llama una rama divergente. Al seleccionar una fila más antigua se previsualiza en el sitio con su copia de trabajo guardada por referencia, y mientras hay una vista previa activa ambos caminos de guardado rechazan el documento de plano. Restaurar es la única acción que escribe: primero vuelve a leer la revisión viva del servidor, pregunta antes de sobrescribir un cambio que llegó mientras usted miraba, pregunta de nuevo antes de descartar sus ediciones sin guardar, y luego se encadena a la revisión más fresca conocida para que la restauración aterrice limpiamente en la cabeza.
guardar, capturado en el servidor un instante después
Lo que no hay, en detalle: ni ramas, ni vista de comparación o diferencias, ni fusión, ni mensajes de commit. El historial es por programa, no por proyecto. Los números de versión son posicionales, así que la v3 de hoy no es la v3 de la semana que viene. Se conservan cincuenta instantáneas por documento y el resto se eliminan en lugar de archivarse. La captura es asíncrona y del lado del servidor, así que un guardado reciente se muestra como registrando hasta que aterriza. Y deshacer es un sistema distinto que no comparte nada con este: cincuenta pasos por documento, agrupados con un margen de cuatrocientos milisegundos para que un arrastre o una ráfaga de escritura sea un solo paso, limitado al nodo que usted tenga seleccionado, guardado solo en la memoria del navegador y perdido en cuanto recarga. Tras una recarga, este carril es la única vuelta atrás.
Hay un bloqueo. No hay fusión.
El bloqueo es un check-in, y es por nodo. El guardado depende de él: un nodo con check-in de otra persona se rechaza indicando el nombre de quien lo tiene, y un nodo del que nadie ha hecho check-in se rechaza con Haga check-in, tras recorrer la cadena de padres para ver si algo por encima está retenido. Los borradores están exentos, y también una aplicación que nunca se ha guardado. Lo que no está bloqueado es el desenlace una vez que una revisión de otra persona sí llega a un documento que usted tiene abierto. Studio decide entre exactamente tres opciones, y calcula si usted tiene ediciones sin guardar antes de actualizar su referencia, y ese orden es lo que hace fiable la respuesta.
- 01
Su copia está limpia, así que se queda con la de la otra persona entera
No hay nada suyo en juego, así que Studio adelanta el documento abierto a la revisión de la otra persona por completo y refresca el indicador de la pestaña de inmediato, sin esperar al observador limitado. Usted se entera porque el contenido cambió bajo sus pies, no porque un diálogo se lo preguntara.
- 02
Usted tiene ediciones, y la escritura de la otra parte fue del compilador
Studio compara los dos documentos dejando fuera la lista de revisiones, los metadatos de studio, el resultado de compilación, el error de compilación, las tres marcas de tiempo y las dependencias del script. Cuando lo que queda es idéntico, la revisión entrante es el worker de compilación guardando su propia salida. Sus ediciones se quedan exactamente donde están, solo se adoptan la revisión y los campos de compilación, y no se le avisa, porque a usted no le ha pasado nada.
- 03
Usted tiene ediciones, y el contenido de la otra parte sí difiere
Se conservan todas sus ediciones y solo se incrementa la revisión, de modo que su siguiente guardado se encadena al de la otra persona en vez de colisionar. Después se le avisa durante doce segundos: un colaborador guardó este documento, y sus ediciones sin guardar sobrescribirán los cambios de esa persona cuando usted guarde. El aviso tiene exactamente una acción, descartar las mías y usar las suyas, que sustituye su copia de trabajo por el documento del servidor. Ignórelo y guarde, y su versión será la que sobreviva. No hay fusión a nivel de campo, ni comparación, ni presencia, ni cursores compartidos.
Un único archivo comprobador, ejecutado en su navegador o en el servidor según dónde esté usted.
La validación no es un servicio en otro sitio. Es un único archivo, runtime/js/modules/xuda-studio-checker.mjs, de 4714 líneas, importado directamente por el front end de Studio e importado por ruta en el servidor por el módulo de la aplicación. Studio decide en el momento de la llamada quién lo ejecuta. En línea, y en un proyecto que no es un borrador, lanza run_programs_checker como trabajo en segundo plano. Sin conexión, o dentro de un borrador, ejecuta la misma comprobación sobre cada programa en el navegador y registra un resultado con la misma forma. Los hallazgos se dividen en errores y advertencias por nada más que un campo de tipo E o W. Y ahora la parte honesta: no detiene una compilación. build_app recibe ignore_errors con valor por defecto true, ningún punto de llamada del producto envía nunca false, y el total de errores se escribe en la propia versión, así que cada versión registrada lleva el número de errores con los que se publicó.
- Dieciocho funciones de comprobación se reparten entre once tipos de programa: globals, table, component, javascript, get_data, set_data, batch, api, alert, route y ai_agent. Una carpeta es deliberadamente una operación vacía, y cualquier tipo no reconocido genera CHK_MSG_GEN_050.
- Una ejecución en el servidor escribe un documento de comprobación por programa, con clave en esa revisión del programa, de modo que un programa que nadie ha tocado desde la última pasada se omite directamente en vez de volver a comprobarse.
- Cada código del catálogo generado lleva los mismos campos: título, severidad, dominio, categoría, resumen, causas, pasos de resolución, un slug de ayuda, patrones heredados y códigos relacionados. Se genera a partir del registro de errores, no se escribe a mano.
- Los dos entornos no producen una salida idéntica. La ejecución en el servidor se inicializa con la lista de despliegues y puede marcar un programa como usado por un despliegue. La ejecución en el navegador no, así que el veredicto de no está en uso difiere entre ambas.
Una compilación y un despliegue son objetos distintos, y una versión se sitúa entre ambos.
Compilar escribe una instantánea numerada. Desplegar apunta una máquina hacia una de ellas. El número de la insignia, #37, es app_build_id, un contador por proyecto que sube de uno en uno cada vez que se ejecuta build_app. El 1.4.0 que aparece al lado es una cadena aparte que usted escribe, validada por un patrón simple de mayor, menor y parche en la propia insignia. Se mueven de forma independiente, y ambos quedan sellados en el documento del despliegue, de modo que un despliegue siempre registra exactamente qué instantánea está sirviendo.
Pulsar desplegar no instala nada.
La llamada de despliegue es la primera mitad de un apretón de manos. Crea registros, pide una máquina y retorna mientras la máquina todavía se está creando. La instalación empieza cuando la propia máquina llama de vuelta a la plataforma, y por eso la barra de progreso puede quedarse quieta un rato a mitad de camino y por eso la escalera de estados tiene un peldaño de espera: 1 creado, 2 instalando o esperando, 3 activo, 4 fallido o terminado.
- 01
El formulario retorna antes de que exista nada
deploy_app escribe el documento del despliegue, opcionalmente un documento de centro de datos, pide al proveedor que cree una máquina de forma asíncrona y le devuelve el control. No se ha instalado nada y no se ha copiado nada. El despliegue se queda en el código de estado 2 con la descripción servidor de la granja esperando a instalar, y realmente no hay nada más que mostrar hasta que el siguiente paso ocurra por su cuenta.
- 02
La máquina llama de vuelta a la plataforma
El primer arranque de la máquina nueva hace curl a un webhook de la plataforma con el id de la aplicación. Ese manejador reabre el mismo trabajo que usted ya está mirando, sustituye su lista de pasos por la lista de instalación de veinticuatro entradas y ejecuta install_hosting_resources. El trabajo que usted inició para la fase uno es el que informa de la fase dos, y por eso los nombres de los pasos cambian a mitad de camino.
- 03
La instalación se ejecuta, reintenta si hace falta y aterriza en el estado 3
La instalación se envuelve en cuatro intentos con treinta segundos de espera, porque una máquina recién creada puede seguir reiniciándose cuando llega la primera conexión SSH. Escribe el archivo de ecosistema de pm2, ejecuta pm2 delete y luego pm2 start contra él, y termina en el código de estado 3, servidor listo. Esta página no da una duración para nada de esto, porque en el código fuente no consta ninguna y nosotros no la medimos.
Dieciséis tipos de despliegue, y lo que ejecuta realmente cada uno.
El mismo proyecto se publica en dieciséis tipos de despliegue declarados, en cuatro grupos: seis web, cinco de servidor, tres de escritorio y dos móviles. Cada tipo declara además su propio conjunto de pestañas a partir de una lista base de catorce, así que un despliegue cron descarta lanzamiento, dominio, cortafuegos, analítica y asistencia al usuario y se queda en nueve pestañas, mientras que una MPA conserva las catorce y los cinco tipos de artefacto insertan una pestaña de publicación en su lugar. Agrupados por lo que la instalación escribe realmente en el archivo de ecosistema de pm2, quince de ellos se reducen a cinco formas. El decimosexto, mcp, se declara junto a los demás y no tiene una entrada de ecosistema propia que hayamos podido rastrear.
Qué se ejecuta en la máquina | Qué lanza | |
|---|---|---|
| Web: spa, mpa, pwa, embed | Una aplicación de pm2 llamada webserver, en modo de ejecución cluster con instances en max, más una unidad de systemd para el enrutador de websockets | El paquete de runtime sellado por la compilación sobre HTTPS en el puerto 443, escuchando en un socket de doble pila |
| Web: preview | La misma aplicación webserver, y una segunda aplicación de pm2 llamada preview | Una salida de servidor Nuxt en el puerto 3023 junto a la propia aplicación |
| Web: user group | La misma aplicación webserver, y una segunda aplicación de pm2 llamada user_group | Una salida de servidor Nuxt en el puerto 3022 para la superficie de grupo |
| Servidor: cron, api, node, emitter | Una única aplicación de pm2 en modo de ejecución fork, ejecutando el archivo de entrada de ese tipo, xuda-cron.mjs o xuda-api.mjs y así sucesivamente | El paquete de servidor de esta compilación. Un disparo de cron bifurca un proceso hijo, espera a que informe que está listo, le envía la ejecución y registra lo que devuelve |
| Artefactos: ios, android, macos, windows, linux | Nada. La ruta de macOS omite deliberadamente la llamada de despliegue y escribe un documento de despliegue sin ninguna máquina de alojamiento detrás | Una pestaña de publicación y un envío a un servicio de compilación externo. Rastreamos lo suficiente para saber que es otra tubería distinta, no lo suficiente para describirla aquí |
Un intérprete, dos lados, una llamada.
Lo que un despliegue publica realmente no es código fuente generado ni un binario compilado. Es un paquete intérprete más su árbol de programas en JSON, y el mismo intérprete se ejecuta a ambos lados del cable. En el navegador, eso es una etiqueta script y un constructor. En el servidor, es un import dinámico del paquete hermano y una bandera. Cuando una página se renderiza del lado del servidor, el servidor pide al worker que ejecute un programa hasta obtener una cadena, y recibe de vuelta tanto el marcado como un payload. El payload se incrusta en la página, y el elemento de montaje se marca con el modo de renderizado y la activación de cliente que el servidor resolvió para él.
La categoría del nombre del paquete decide dónde aparece un plugin.
Los 62 plugins propios se nombran de la misma manera, y la categoría de ese nombre también está en el registro del plugin. Esa es toda la regla de enrutamiento: instale uno y aparecerá en el selector de datasource, en la barra de inserción, en el selector de iconos o en la lista de acciones de flujo de trabajo, sin nada que conectar. Una instalación tampoco es una marca de funcionalidad. El servidor escribe un registro en el proyecto con la versión, el tipo y el manifiesto de archivos, ejecuta un npm install real en el directorio de plugins de ese proyecto, sincroniza ese directorio hacia los servidores y copia todo el árbol de archivos del paquete en la base de datos del proyecto con clave por ruta relativa.
Nueve cosas que Studio no hace.
- La caja de texto de la pantalla de inicio de Studio no construye nada: envía una petición de chat normal limitada a 1024 tokens y, con los mensajes ocultos, la respuesta ni siquiera se renderiza, porque el constructor vive en el panel de IA de un proyecto que ya está abierto.
- Elegir Plantilla no abre una galería dentro del editor: abre el asistente de creación del panel de control en una segunda pestaña del navegador, y el proyecto que bifurca es una instantánea sin nada que después lo vincule con su origen.
- Un borrador no está en un servidor: vive en un perfil de navegador de un solo dispositivo hasta que usted pulsa Guardar, y borrar los datos del sitio acaba con él.
- El check-in que condiciona el guardado no es una concesión del servidor: es un campo del documento, así que un guardado que nunca llega al servidor nunca lo libera, y nada fusiona dos ediciones por usted.
- Nada puede hacer que una compilación falle por errores de validación: el comprobador se ejecuta primero y su total de errores se escribe en la versión, pero ningún punto de llamada pide a la compilación que se niegue.
- Una compilación terminada no toca nada que ya esté en producción, y dos despliegues de un mismo proyecto pueden quedarse en números de compilación distintos todo el tiempo que usted los deje así.
- No hay despliegue por fases: la insignia de compilación puede mostrar un aviso de preparado pero no en producción, pero una compilación normal asigna el mismo valor al número preparado y al de producción, así que ese aviso no puede aparecer.
- No hay recorte del runtime por aplicación, así que cada despliegue publica el mismo paquete intérprete completo de su compilación y solo cambia el JSON de los programas.
- Un despliegue programado no ejecuta una pantalla, solo programas batch, get_data y set_data, y un paso de JavaScript del lado del servidor se detiene a los sesenta segundos.
Las preguntas que se está haciendo ahora mismo
Cada una de estas siete respuestas termina en un límite. Están aquí porque usted se toparía con las siete en la primera semana de todos modos.
Vea a Studio abrir un proyecto y rellenar el árbol.
Abra un proyecto vacío y vea lo que se escribe.
Dos documentos, una ruta, y el editor está abierto. Nada llega a un servidor hasta que usted guarda, y nada llega a un visitante hasta que usted compila y luego mueve un despliegue a esa compilación a propósito.