Traducción no oficial al español rioplatense, generada con IA (Claude Sonnet 5.5) bajo la dirección y revisión de Jassiel Ovando. No es una publicación de Typst GmbH ni cuenta con su aval; ante cualquier duda, prevalece la documentación oficial en inglés. ¿Un error de traducción o una sugerencia? Reportalo. Tipografía: Reforma, de PampaType.

pluginDesde: 0.8.0Ir al código fuente

Carga un módulo de WebAssembly.

El módulo resultante contendrá una función de Typst por cada función exportada del módulo de WebAssembly cargado.

Los plugins de WebAssembly de Typst tienen que seguir un protocolo específico. Para ejecutarse como plugin, un programa debe compilarse como biblioteca compartida de WebAssembly de 32 bits. Las funciones de un plugin pueden aceptar varios buffers de bytes como argumentos y devolver un único buffer de bytes. Normalmente deberían envolverse en funciones idiomáticas de Typst que realicen las conversiones necesarias entre los tipos nativos de Typst y los bytes, aprovechando str, bytes y las funciones de carga de datos.

Por razones de seguridad, los plugins se ejecutan aislados de tu sistema. Esto significa que no se admite imprimir, leer archivos ni cosas similares.

Ejemplo

#let myplugin = plugin("hello.wasm") #let concat(a, b) = str( myplugin.concatenate( bytes(a), bytes(b), ) ) #concat("hello", "world")

Como la función plugin devuelve un módulo, se puede usar con la sintaxis de importación:

#import plugin("hello.wasm"): concatenate

Pureza

Las funciones de un plugin deben ser puras: una llamada a una función de un plugin no debe tener ningún efecto secundario observable en futuras llamadas al plugin y, dados los mismos argumentos, siempre debe devolver el mismo valor.

La razón es que las funciones de Typst deben ser puras (algo bastante fundamental en el diseño del lenguaje) y, como las funciones de Typst pueden llamar a funciones de plugins, este requisito se hereda. En particular, si una función de un plugin se llama dos veces con los mismos argumentos, Typst podría almacenar en caché los resultados y llamar a tu función una sola vez. Además, Typst puede ejecutar varias instancias de tu plugin en varios hilos, sin estado compartido entre ellas.

Typst no obliga a que las funciones de los plugins sean puras (por razones de eficiencia), pero llamar a una función impura llevará a resultados impredecibles e irreproducibles y debe evitarse.

Dicho esto, las operaciones mutables pueden ser útiles para plugins que requieren una inicialización costosa en tiempo de ejecución. Debido al requisito de pureza, esa inicialización no se puede realizar mediante una llamada normal a una función. En cambio, Typst expone una API de transición de plugins, que ejecuta una llamada a una función y luego crea un módulo derivado con funciones nuevas que observarán los efectos secundarios producidos por la llamada de transición. El plugin original no se ve afectado.

Plugins y paquetes

Cualquier código de Typst puede usar un plugin simplemente incluyendo un archivo de WebAssembly y cargándolo. Sin embargo, como la interfaz de plugins basada en bytes es de muy bajo nivel, los plugins suelen exponerse a través de un paquete que contiene el plugin y funciones envoltorio idiomáticas.

WASI

Muchos compiladores usan por defecto, o como única opción, la ABI de WASI (por ejemplo, emscripten), que permite imprimir, leer archivos, etcétera. Esta ABI no funciona directamente con Typst. Vas a tener que compilar a otro destino o reemplazar todas las funciones por stubs.

Protocolo

Para usarse como plugin, un módulo de WebAssembly debe cumplir el siguiente protocolo:

Exportaciones

Un módulo de plugin puede exportar funciones para que se puedan llamar desde Typst. Para cumplir el protocolo, una función exportada debe:

Importaciones

Los módulos de plugin necesitan importar dos funciones que provee el entorno de ejecución. (Los tipos y las funciones se describen con la sintaxis de WAT.)

Recursos

Para más recursos, mirá el repositorio wasm-minimal-protocol. Contiene:

Parámetros

plugin(strpathbytes) → module

source
str o path o bytes
ObligatorioPosicional
Signo de pregunta

Una ruta a un archivo de WebAssembly o bytes de WebAssembly sin procesar.

Funciones
Signo de pregunta

transitionDesde: 0.13.0Ir al código fuente

Llama a una función de un plugin que tiene efectos secundarios y devuelve un módulo nuevo con funciones de plugin que garantizadamente observaron los resultados de la llamada mutable.

Tené en cuenta que llamar a una función impura mediante una llamada normal a una función (sin usar la API de transición) está prohibido y lleva a un comportamiento impredecible. Leé la sección sobre pureza para más detalles.

En el siguiente ejemplo, cargamos el plugin hello-mut.wasm, que exporta dos funciones: la función get() obtiene un array global como cadena de texto. La función add(value) agrega un valor al array global.

Llamamos a add mediante la API de transición. La llamada mutated.get() en el módulo derivado observará la adición. Mientras tanto, el módulo original permanece intacto, como demuestra la llamada base.get().

Nota: Debido a limitaciones de la implementación interna de WebAssembly, la API de transición solo puede garantizar que se reflejen los cambios en la memoria del plugin, no en los globales de WebAssembly. Si tu plugin depende de que los cambios en los globales sean visibles después de la transición, quizás quieras evitar por ahora el uso de la API de transición. Esperamos levantar esta limitación en el futuro.

#let base = plugin("hello-mut.wasm")
#assert.eq(base.get(), "[]")

#let mutated = plugin.transition(base.add, "hello")
#assert.eq(base.get(), "[]")
#assert.eq(mutated.get(), "[hello]")
plugin.transition() → module

func
function
ObligatorioPosicional
Signo de pregunta

La función del plugin a la que se llama.

arguments
bytes
ObligatorioPosicional
Signo de pregunta
Variádico
Signo de pregunta

Los buffers de bytes con los que se llama a la función.