Saltar al contenido
Meeko
Escribe para buscar en las guías y en la referencia de la API. Ábrela desde cualquier página con / o Ctrl K; muévete con las flechas y entra con Intro.
Empezar
En esta página

Cambios de Meeko

1.9.0 — 2026-11-05#

  • Credenciales configurables en los clientes API y RPC. ClientOptions.credentials acepta same-origin, include u omit y conserva same-origin por defecto. Permite usar cookies HttpOnly con una API en otro origen desde el navegador sin reemplazar el fetch del cliente. El servidor debe configurar CORS y proteger las mutaciones contra CSRF; esta opción no reenvía automáticamente las cookies de una petición SSR.

1.8.0 — 2026-11-04#

  • defineModel también como prop y evento. Un componente con defineModel sólo aceptaba una señal escribible, y quien venía de Vue o tenía el valor en un objeto (bind="option.props") no podía pasarlo. Ahora, sin cambiar el hijo, acepta también bind:modelValue con on:update:modelValue, bind:nombre con on:update:nombre y la prop dentro de bind="objeto". Con prop y evento, el padre decide cada escritura y el control vuelve al valor de la prop si no la cambia; con sólo la prop, la escritura se queda en el hijo hasta que la prop cambie; con sólo el evento, se queda en el hijo y además llama al evento. El HTML del servidor sale con el valor de la prop, que no viaja en el estado del hijo. ComponentProps, <Nombre>Props, <Nombre>Emits, meeko check y el editor los conocen, y next tiene el tipo del modelo. model junto a bind:modelValue u on:update:modelValue es MEEK066, y declarar la prop o el evento del modelo en el script es MEEK063.

  • Un padre con await ya no pierde lo que se escribe. Si el manejador de on:update:modelValue devuelve una promesa, el hijo conserva lo escrito hasta que termine la última escritura, y entonces vuelve a seguir a la prop. El cursor no salta, una escritura anterior que termina después no pisa el valor y un rechazo llega al manejador de errores en lugar de quedar sin capturar. Un manejador síncrono no cambia.

  • Un modelo obligatorio que falta se explica. meeko check y el editor decían Property '"default"' is missing in type '{}', con un nombre interno. Ahora dicen cómo pasarlo: model="señal" o bind:modelValue="valor", y el código sigue siendo TS2741.

  • bind="{ … }" en una etiqueta de componente ya no ofrece en el editor las claves on*, que luego daban MEEK113.

  • MEEK101 ya no avisa de una prop leída en el default de defineModel. defineModel<string>({ default: props.initial ?? "" }) la lee una vez a propósito, como signal(props.initial).

  • Atrás y adelante devuelven al lector a donde estaba. Al volver de una página corta a una larga, el navegador restauraba el desplazamiento sobre la corta y lo recortaba: de scrollY 100.000 se acababa en 6.226. Ahora cada entrada del historial recuerda su posición, que se aplica junto con el DOM de la página, también dentro de una View Transition, y espera al contenido que aún no ha llegado sin quitarle la página a quien la mueva. Una entrada con fragmento vuelve a su posición, no al ancla. Meeko pone history.scrollRestoration en manual y añade meekoEntry a history.state, donde ya no borra lo que guarde otro código.

  • Un módulo de componente en un signal o en useState ya no llega al 500 sin aviso. signal([{ component: AppCard }]) pasaba meeko check y fallaba en cada render de servidor, porque el estado se envía al navegador como JSON. Ahora es MEEK136 donde se escribe el valor, en meeko check y en el editor, con la salida: guardar en el estado qué entradas se pintan y leerlas con un computed. Mira el valor inicial, no el tipo de la señal, así que signal<ResolvedComponent<"AppCard"> | undefined>(undefined), que se llena en el navegador, sigue siendo válido. Un componente que nunca se renderiza en el servidor también recibe el error, aunque ahí no fallaría. El error de ejecución nombra también la señal, o la clave de useState, y el camino hasta el módulo.

  • type X = keyof typeof entries con una constante del setup explica el problema. Daba TS2304 y dejaba detrás un any con errores confusos en la plantilla. Ahora meeko check da MEEK137, una sola vez, con la salida. La compilación no cambia: los tipos se borran, así que sigue funcionando en ejecución.

  • Un componente genérico en una lista de módulos distintos ya no da un falso MEEK113. Con is="option.component" bind="option.props", una prop como format: (item: number) => string se comparaba con T en unknown. De un genérico en esa lista se comprueban sus nombres y sus props obligatorias.

  • <component is> con módulos que llegan en los datos y bind. is="option.component" bind="option.props" daba MEEK113: placeholder no es un atributo de la etiqueta, porque el objeto se comprobaba también como atributos de una etiqueta que ese is nunca podía ser; pasaba lo mismo con una prop, un computed o el parámetro de un snippet. Ahora cada clave se comprueba contra lo que is puede ser, una prop de sus componentes o un atributo de sus etiquetas. Con una lista de módulos distintos, cada entrada se comprueba contra su propio componente sin tipos auxiliares: unas props equivocadas dan MEEK113 en bind, con la prop que sobra o falta, en lugar de un TS2345 sobre la intersección de todas. Basta con que is y bind lean el mismo objeto. En ejecución no cambia nada. Véase la lista de <component is>.

  • TS2367 falso en is="option.kind === 'a' ? 'AppA' : 'AppB'". El código de comprobación repetía la condición de is dentro de su propia rama y TypeScript la comparaba consigo misma. Cada rama sigue estrechando sus props.

  • MEEK112 explica qué hacer con el nombre de un componente que llega como texto. Con component: "AppSelect" en los datos, el mensaje ofrece el literal en la plantilla, el módulo importado o resolveComponent, en meeko check, en el editor y en el TypeError de ejecución. is sigue sin interpretar nunca un texto, y el error ya no viene acompañado de un TS2345 sobre el objeto de bind. Además, MEEK113 por una clave on* propone el alias AppInputProps si el componente usa ComponentProps<'AppInput'>, que incluye los eventos.

  • Navegar desde o hacia una página muy larga ya no la congela. Con viewTransitions, una página de más de 4.000 elementos, de origen o de destino, navega sin transición. En una guía de 24.000 elementos con DPR alto o en un móvil, cada frame de la transición bloqueaba la página durante segundos. isTooLargeToAnimate(), nuevo en @meekojs/meeko, es la misma comprobación para quien llame a document.startViewTransition() por su cuenta.

  • @meekojs/meeko/i18n pide a la vez los catálogos de una página. Cada namespace esperaba al anterior, así que cada uno costaba al visitante una ida y vuelta antes de hidratar. Ahora se piden juntos, también al navegar. No cambian la API ni el orden de fusión. Si falla un catálogo, el error sigue siendo el del primero de la lista que falla, lo anterior se conserva y lo posterior no se fusiona, aunque ya se ha pedido.

  • Un schema con un import sin resolver ya no se confunde con un schema sin tipos. Con moduleResolution: "NodeNext", un import relativo sin extensión deja el schema en any, y la generación de contratos de API, RPC y Socket pedía «tipos de Standard Schema concretos» sin nombrar la causa. Ahora dice qué import no se resuelve y remite a la ruta y a moduleResolution.

  • documentHtml: el HTML de una página viaja una vez. Un dato que se pinta con html="..." llegaba dos veces en la primera carga: en el HTML del documento y, más pesado por el escape de JSON, en el payload de hidratación. En la guía más grande de meekojs.com eran 1,8 MiB de 3,3. documentHtml(trustHtml(html)), de @meekojs/meeko/framework, deja en el payload un marcador: la hidratación adopta el contenido sin leerlo ni reescribirlo, una navegación sigue recibiendo el valor, y volver a pintar el elemento lo pide al servidor, nunca al DOM, e inserta sólo lo que esa respuesta declara marcado; si ya no está, carga el documento de nuevo. Hay que marcarlo a propósito, porque en esa primera carga el navegador ve el marcador y no el valor: sólo sirve para lo que nada más lee. Sin la marca nada cambia. Véase documentHtml.

  • Con cualquier htmlWhitespaceSensitivity, también la de por defecto y en el editor sin configuración de proyecto, formatear un .meeko ya no cambia lo que se renderiza. Partir <li each:of="a" each:as="b">{b}</li> en varias líneas o separar <button>a</button><button>b</button> añadía nodos de texto, también en los bordes de <template>, y Hi<b> you</b> perdía su espacio. Ahora ningún espacio aparece ni desaparece en el límite entre dos nodos, en el plugin del núcleo y en @meekojs/prettier-plugin; sólo puede cambiar de forma, de un espacio a un salto de línea con sangría, que se pinta igual salvo con white-space: pre. El compilador no cambia, así que el HTML de una aplicación tampoco, y un archivo ya formateado conserva sus espacios y casi siempre queda igual. La salida del formato sí cambia en lo que no tenía espacios: los saltos de línea quedan dentro de las etiquetas (>{b}</li\n>). Véase editors.md.

  • El texto tras el salto de línea inicial de <pre>, <listing> o <textarea> ya no pierde caracteres. El compilador lee el texto de la fuente, y parse5 lo situaba después del primer carácter que producía: <textarea> &amp;x</textarea> se pintaba ;x, y `

¿Te sirvió esta página?

Añadir un comentario

Se envía al elegir «Sí» o «No». Solo se guardan la página, tu respuesta y el comentario: ni cookies ni datos tuyos.

0 de 2000 caracteres

Editar en GitHub: CHANGELOG.md