Apps conectadas.
Construye un comando en React. Vue recibe el evento y observa el mismo estado.
El contador y los eventos usan las APIs reales de WU. Desmontar libera los recursos de la aplicación; el estado compartido permanece durante esta sesión. Los comandos se copian para ejecutarlos en tu terminal. Referencia de wu create →
Del control al código
Fuentes de las dos aplicaciones que acabas de usar.
Leer cómo se conectan el store, los eventos y las suscripciones
Estos fragmentos se extraen de las fuentes enlazadas. Ambos módulos registran su lifecycle con wu.define y reciben mount(container, {wu: scoped}): scoped es la fachada de esa app. COUNTER es docs.lab.counter y LAST_COMMAND, docs.lab.lastCommand.
React: escribir y reflejar el valor compartido
+1 desde React ejecuta estas líneas del manejador del control. La escritura actualiza el dato compartido; el evento añade una entrada al inspector.
const next=(scoped.store.get(COUNTER)??0)+1;
scoped.store.set(COUNTER,next);
scoped.emit('docs:lab:counter',{value:next,source:'React'});React lee una vez con useState y conecta store.on dentro de useLayoutEffect. Cada notificación llama a setCounter. Al desmontar el root de React, la limpieza del efecto ejecuta dispose(). alive evita actualizar mensajes de una instancia retirada; diagnostics cuenta sus listeners.
const [counter,setCounter]=useState(()=>scoped.store.get(COUNTER)??0);
useLayoutEffect(()=>{
alive.current=true;
const dispose=scoped.store.on(COUNTER,value=>setCounter(value??0));
diagnostics.listeners+=1;
return ()=>{alive.current=false;dispose();diagnostics.listeners-=1;};
},[scoped]);Publicar en el bus guarda el comando y emite el hecho. result procede de buildCommand, el generador de texto de esta app; draft contiene el formulario.
scoped.store.set(LAST_COMMAND,result.command);
const accepted=scoped.emit('docs:lab:command',{command:result.command,framework:draft.framework,operation:draft.operation});
setStatus(accepted?tr("Comando publicado. Runtime Lab recibe el evento."):tr("El host no concedió permiso para publicar el evento."));Vue: observar, pausar y volver a leer
Vue crea state con reactive. connectLeaves() registra dos suscripciones al store y tres al bus; track conserva cada función de baja. Los callbacks cambian state.counter y state.lastCommand; receive convierte el envelope del evento en una fila del historial.
const connectLeaves=()=>{
if(disposers.length)return;
try {
const track=dispose=>{disposers.push(dispose);diagnostics.listeners+=1;};
track(scoped.store.on(COUNTER,value=>{state.counter=value??0;}));
track(scoped.store.on(LAST_COMMAND,value=>{state.lastCommand=value??'';}));
for(const name of ['docs:lab:command','docs:lab:counter','docs:lab:lifecycle'])track(scoped.on(name,receive));
state.counter=scoped.store.get(COUNTER)??0;state.lastCommand=scoped.store.get(LAST_COMMAND)??'';state.connected=true;sync();
}catch(error){disconnect();throw error;}
};store.on no entrega automáticamente el valor inicial: las lecturas get al conectar recuperan también los cambios ocurridos durante la pausa. Las notificaciones del store llegan mediante microtasks; la escritura ya es visible para get.
Pausar suscripciones y unmount llaman a disconnect(). Este recorre las bajas guardadas; sync() copia los contadores de diagnóstico al estado de Vue. Desmontar también retira el listener DOM y ejecuta app.unmount().
disconnect=()=>{
const pending=disposers;disposers=[];
for(const dispose of pending){dispose();diagnostics.listeners-=1;diagnostics.cleanups+=1;}
state.connected=false;sync();
};Conectarlo a tu propia interfaz
Elige tus paths y eventos, conserva la lectura inicial y vincula cada baja al lifecycle del consumidor. Declara las solicitudes en el manifest y los grants en tu shell: manifest React, manifest Vue y cómo conceder permisos. Los hosts independientes de React y Vue muestran el registro, la inicialización y el montaje de una app.
En esta demo, React y Vue adaptan el estado a la propiedad model de controles Lit y reciben sus eventos DOM wu-command-intent y wu-runtime-intent. Puedes leer los controles del productor, los controles del consumidor y sus estilos compartidos, o conectar estas mismas operaciones de WU a tus controles. Las fuentes conservan los imports y la estructura del proyecto del portal.
Continúa con las reglas del store y sus patrones wildcard y el contrato del bus de eventos.