Ir al contenido

Adapter de Svelte

El adapter de Svelte tiene dos puntos de entrada porque Svelte cambió la forma de instanciar componentes entre la v4 y la v5. Elige el que corresponda a tu compilador.

Ventana de terminal
npm install wu-framework svelte
// src/main.js — la micro-app
import { wuSvelte } from 'wu-framework/adapters/svelte';
import App from './App.svelte';
wuSvelte.register('orders', App); // Svelte 3/4
// wuSvelte.registerSvelte5('orders', App); // Svelte 5
register() registerSvelte5()
Instancia con new Component({ target, props, context, intro }) mount(Component, { target, props }) de svelte
Versiones de Svelte 3, 4 5 (recurre a la API antigua si falta mount en svelte)
Props vivas (update) — vía $set() no
Opciones context / intro no
Contenedor por defecto #app #app
await wuSvelte.register('orders', App, {
props: { apiUrl: 'https://api.example.com' },
context: new Map([['theme', 'dark']]),
intro: false,
standaloneContainer: '#app',
onMount: (container, instance) => console.log('montado', instance),
onUnmount: (container, instance) => console.log('destruyendo'),
});
Opción Tipo Por defecto Notas
props object {} Props iniciales.
context Map new Map() Se pasa tal cual a la opción context de Svelte — legible con getContext() en cualquier punto del árbol.
intro boolean false Ejecuta las transiciones de entrada en el primer render. Desactivado por defecto para que un montaje dentro de un shell no anime de forma inesperada.
standalone boolean true Plan B standalone.
standaloneContainer string '#app' Selector usado en modo standalone.
onMount function null (container, instance) => void.
onUnmount function null (container, instance) => void, antes de $destroy().

Devuelve Promise<boolean>.

Ambos puntos de entrada añaden dos props a las que hayas pasado:

<script>
export let wuAppName; // 'orders'
export let wuInstance; // la instancia de Wu, o null
export let apiUrl; // tus propias props
</script>
await wu.update('orders', { apiUrl: 'https://staging.example.com' });

El adapter llama a instance.$set(nextProps). La reactividad de Svelte hace el resto: sin remontar y sin perder el estado del componente.

registerSvelte5(appName, Component, options)

Sección titulada «registerSvelte5(appName, Component, options)»
import { wuSvelte } from 'wu-framework/adapters/svelte';
import App from './App.svelte';
wuSvelte.registerSvelte5('orders', App, {
props: { apiUrl: 'https://api.example.com' },
standaloneContainer: '#app',
});

Acepta props, onMount, onUnmount, standalone y standaloneContainer; sin context, sin intro.

El adapter importa dinámicamente svelte y usa su mount(). Si ese import falla o no existe mount, avisa y recurre a la instanciación clásica de Svelte 3/4 sobre el mismo contenedor, de forma que una configuración desajustada se degrada en vez de romperse.

Ningún punto de entrada anuncia hydrate. El markup de servidor producido por wu-framework/server se monta encima en lugar de adoptarse: la salida es correcta, solo que repintada. Consulta Hidratación para ver qué adapters sí lo adoptan.

Los helpers del adapter implementan el contrato de stores de Svelte, así que funcionan con la sintaxis de auto-suscripción $store y el compilador los limpia por ti.

<script>
import { createWuStore } from 'wu-framework/adapters/svelte';
const user = createWuStore('user');
$: userName = $user?.name;
function rename(name) {
user.set('name', name);
}
</script>
<h1>Hola {userName}</h1>

Se suscribe directamente a la ruta del namespace, que recibe tanto las escrituras exactas (set('user', {...})) como las anidadas (set('user.profile.name', x)): el notify del store recorre las rutas padre. Un patrón ns.* no vería ninguna de las dos.

set(path, value) escribe en <namespace>.<path>.

<script>
import { createWuEventStore } from 'wu-framework/adapters/svelte';
const userEvents = createWuEventStore('user:*');
$: if ($userEvents) {
console.log('Evento de usuario:', $userEvents);
}
</script>

Un store de solo lectura con el último evento que coincide con el patrón. Útil para reacciones $:; no es una cola — las ráfagas rápidas se sobrescriben entre sí.

<script>
import { onDestroy } from 'svelte';
import { useWuEvents } from 'wu-framework/adapters/svelte';
const { emit, on, cleanup } = useWuEvents();
on('user:login', (e) => console.log('ha iniciado sesión', e.data));
onDestroy(cleanup);
</script>
<button on:click={() => emit('cart:add', { sku: 'A1' })}>Añadir</button>
<script>
import { createWuAIStore } from 'wu-framework/adapters/svelte';
const ai = createWuAIStore({ namespace: 'support' });
$: ({ messages, isStreaming, error } = $ai);
</script>
{#each messages as m (m.id)}
<p class={m.role}>{m.content}</p>
{/each}
<button on:click={() => ai.send('Muestra los pedidos pendientes')} disabled={isStreaming}>
Preguntar
</button>
<button on:click={ai.clear}>Limpiar</button>

Un store de Svelte cuyo valor es { messages, isStreaming, error }, más los métodos send() y clear(). Llama a wu.ai.send() — sin streaming. Los suscriptores reciben una notificación inmediata al suscribirse. Consulta Visión general de IA.

Los componentes de Svelte se compilan, no se construyen en tiempo de ejecución, así que el adapter no puede incluir un WuSlot.svelte. createWuSlotConfig() devuelve { props, template }, donde template es el código fuente de un componente funcional para que lo guardes como WuSlot.svelte:

import { writeFileSync } from 'node:fs';
import { createWuSlotConfig } from 'wu-framework/adapters/svelte';
const config = createWuSlotConfig();
writeFileSync('src/lib/WuSlot.svelte', config.template);
<script>
import WuSlot from '$lib/WuSlot.svelte';
</script>
<WuSlot name="orders" url="http://localhost:3001" on:load={handleLoad} />

Sus props son name, url, appName y fallbackText, y despacha load, error, mount y unmount.

import {
wuSvelte, // export por defecto
register,
registerSvelte5,
createWuStore,
createWuEventStore,
useWuEvents,
createWuSlotConfig,
createWuAIStore,
getWuInstance,
waitForWu,
} from 'wu-framework/adapters/svelte';

Desde el barrel: registerSvelte, createSvelteWuStore, useSvelteWuEvents.