Adapters de Solid y Preact
Solid y Preact hablan JSX y ambos son pequeños. Difieren en lo único que le importa a un adapter: cómo ocurre un re-render.
Preact hace diffing de un DOM virtual, así que volver a llamar a render() con
props nuevas actualiza en el sitio: eso es un canal de props vivas. Solid compila
la reactividad dentro del componente en tiempo de build; render() se ejecuta
una vez y devuelve una función dispose, así que no existe un “renderiza otra
vez con props nuevas”. Por eso Solid no anuncia update.
| Preact | Solid | |
|---|---|---|
| Subpath | wu-framework/adapters/preact |
wu-framework/adapters/solid |
| 2.º argumento | Component | Component |
| Props vivas | sí (solo register) |
no |
| Hidratación SSR | no | no |
| Contenedor standalone | #app |
#root |
| Punto de entrada extra | registerCompat() |
— |
npm install wu-framework preactimport { wuPreact } from 'wu-framework/adapters/preact';import App from './App';
wuPreact.register('widgets', App);register(appName, Component, options)
Sección titulada «register(appName, Component, options)»| Opción | Tipo | Por defecto |
|---|---|---|
props |
object |
{} |
standalone |
boolean |
true |
standaloneContainer |
string |
'#app' |
onMount |
function |
null |
onUnmount |
function |
null |
Devuelve Promise<boolean>. ensurePreact() resuelve Preact desde el ámbito
global o con un import dinámico; si falla, devuelve false.
Se inyectan dos props en tu componente además de las tuyas:
function App({ apiUrl, wuAppName, wuInstance }) { return <h1>{wuAppName} → {apiUrl}</h1>;}Props vivas
Sección titulada «Props vivas»await wu.update('widgets', { apiUrl: 'https://staging.example.com' });El adapter fusiona las props nuevas y llama a render() sobre el mismo
contenedor. El diff de Preact actualiza el DOM existente: sin desmontar, sin
perder estado.
registerCompat(appName, Component, options)
Sección titulada «registerCompat(appName, Component, options)»Para árboles escritos contra la API de React y que corren sobre preact/compat:
import { wuPreact } from 'wu-framework/adapters/preact';import App from './App'; // componente al estilo React
wuPreact.registerCompat('widgets', App);Importa dinámicamente preact/compat y usa su render y createElement. Si
preact/compat no está instalado, registra un error y delega en
register() con los mismos argumentos, de modo que obtienes una app que
funciona en lugar de un fallo.
createWuSlot(h, hooks)
Sección titulada «createWuSlot(h, hooks)»La factoría de Preact toma dos argumentos: la función h y un objeto de
hooks explícito.
import { h } from 'preact';import { useState, useEffect, useRef } from 'preact/hooks';import { createWuSlot } from 'wu-framework/adapters/preact';
const WuSlot = createWuSlot(h, { useState, useEffect, useRef });
function Shell() { return ( <div> <WuSlot name="widgets" url="http://localhost:3001" /> </div> );}Compáralo con React, donde createWuSlot(React) recibe el namespace completo:
React expone sus hooks en ese namespace, Preact no.
createUseWuEvents(hooks) y createUseWuStore(hooks)
Sección titulada «createUseWuEvents(hooks) y createUseWuStore(hooks)»Mismo patrón: pasa los hooks que importes.
import * as hooks from 'preact/hooks';import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/preact';
const useWuEvents = createUseWuEvents(hooks);const useWuStore = createUseWuStore(hooks);
function Cart() { const { emit, on } = useWuEvents(); const { state, setState } = useWuStore('user'); // …}createUseWuAI(hooks)
Sección titulada «createUseWuAI(hooks)»const useWuAI = createUseWuAI(hooks); // necesita { useState, useCallback }
function Assistant() { const { messages, isStreaming, error, send, clear } = useWuAI({ namespace: 'support' }); // …}Sin streaming: espera a wu.ai.send() y añade la respuesta completa.
Exports de Preact
Sección titulada «Exports de Preact»import { wuPreact, // export por defecto register, registerCompat, createWuSlot, createUseWuEvents, createUseWuStore, createUseWuAI, getWuInstance, waitForWu,} from 'wu-framework/adapters/preact';npm install wu-framework solid-jsimport { wuSolid } from 'wu-framework/adapters/solid';import App from './App';
wuSolid.register('reports', App);register(appName, Component, options)
Sección titulada «register(appName, Component, options)»| Opción | Tipo | Por defecto |
|---|---|---|
props |
object |
{} |
standalone |
boolean |
true |
standaloneContainer |
string |
'#root' |
onMount |
function |
null |
onUnmount |
function |
null |
Devuelve Promise<boolean>. ensureSolid() carga solid-js y solid-js/web;
si falla, devuelve false.
El adapter llama a render(() => Component({ ...props, wuAppName, wuInstance }), container) y guarda la función dispose devuelta para el desmontaje.
createWuStore(namespace)
Sección titulada «createWuStore(namespace)»Devuelve una tupla [getter, setter], la convención de Solid:
import { createWuStore } from 'wu-framework/adapters/solid';
function Profile() { const [user, setUser] = createWuStore('user');
return ( <div> <p>{user()?.name}</p> <button onClick={() => setUser('name', 'John')}>Poner nombre</button> </div> );}user es una señal: hay que llamarla. setUser(path, value) escribe en
<namespace>.<path> del store de Wu. La suscripción a Wu se libera mediante
onCleanup, así que debe llamarse dentro de un componente o de una raíz.
createWuEvent(eventPattern)
Sección titulada «createWuEvent(eventPattern)»import { Show } from 'solid-js';import { createWuEvent } from 'wu-framework/adapters/solid';
function Ticker() { const lastUserEvent = createWuEvent('user:*');
return ( <Show when={lastUserEvent()}> <p>Último evento: {lastUserEvent()?.name}</p> </Show> );}Una señal con el último evento coincidente, desuscrita vía onCleanup.
useWuEvents()
Sección titulada «useWuEvents()»import { onMount } from 'solid-js';import { useWuEvents } from 'wu-framework/adapters/solid';
function Cart() { const { emit, on } = useWuEvents();
onMount(() => on('user:login', (e) => console.log(e.data)));
return <button onClick={() => emit('user:logout', { reason: 'manual' })}>Salir</button>;}createWuContext()
Sección titulada «createWuContext()»import { createWuContext } from 'wu-framework/adapters/solid';
const { WuProvider, useWu, WuContext } = createWuContext();
function App() { return <WuProvider><Inner /></WuProvider>;}
function Inner() { const wu = useWu(); // recurre a getWuInstance() fuera del provider // …}createWuSlot()
Sección titulada «createWuSlot()»No toma argumentos: las primitivas de Solid se resuelven internamente.
import { createWuSlot } from 'wu-framework/adapters/solid';
const WuSlot = createWuSlot();
function Shell() { return ( <div> <WuSlot name="header" url="http://localhost:3001" /> <WuSlot name="content" url="http://localhost:3002" /> </div> );}createWuSlot() arranca ensureSolid() y devuelve de inmediato. Si Solid no ha
terminado de cargar cuando el shell renderiza —lo más probable, ya que los
shells renderizan de forma síncrona justo después—, el slot se degrada a una
versión simple que sigue montando la micro-app, solo que sin primitivas
reactivas. Lanzar un error abortaría el render completo del shell.
createUseWuAI()
Sección titulada «createUseWuAI()»import { createUseWuAI } from 'wu-framework/adapters/solid';
const useWuAI = createUseWuAI();
function Assistant() { const ai = useWuAI({ namespace: 'support' });
return ( <> <For each={ai.messages()}>{(m) => <p>{m.content}</p>}</For> <button onClick={() => ai.send('Hola')} disabled={ai.isStreaming()}>Preguntar</button> </> );}Exports de Solid
Sección titulada «Exports de Solid»import { wuSolid, // export por defecto register, createWuSlot, createWuStore, createWuEvent, useWuEvents, createWuContext, createUseWuAI, getWuInstance, waitForWu,} from 'wu-framework/adapters/solid';Desde el barrel: registerSolid, createSolidWuSlot, createSolidWuStore,
useSolidWuEvents, createSolidUseWuAI.
