import { tr } from '../../../src/lib/ui-i18n.ts'; import React, { useLayoutEffect, useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; import { flushSync } from 'react-dom'; import '../../../packages/lab-ui/src/command-workbench.js'; import { buildCommand, frameworks, shells } from './command.js'; const COUNTER='docs.lab.counter'; const LAST_COMMAND='docs.lab.lastCommand'; const diagnostics={mounts:0,unmounts:0,listeners:0}; export function getDiagnostics(){return {...diagnostics};} function CommandLab({scoped}) { const element=useRef(null); const alive=useRef(true); const [draft,setDraft]=useState({operation:'create',name:'my-platform',framework:'react',shell:'astro',noInstall:true}); const [counter,setCounter]=useState(()=>scoped.store.get(COUNTER)??0); const [status,setStatus]=useState(''); const result=buildCommand(draft); 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]); useLayoutEffect(()=>{ const node=element.current; node.model={...draft,...result,frameworks,shells,counter,status}; const handle=async event=>{ const {action,value}=event.detail; try { if(['operation','name','framework','shell','noInstall'].includes(action)) {setDraft(previous=>({...previous,[action]:value}));setStatus('');return;} if(action==='copy'&&result.command) { if(!navigator.clipboard?.writeText) {setStatus(tr("Selecciona el comando y cópialo con Ctrl+C o ⌘C."));return;} await navigator.clipboard.writeText(result.command); if(alive.current)setStatus(tr("Comando copiado.")); } else if(action==='publish'&&result.command) { 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.")); } else if(action==='increment') { const next=(scoped.store.get(COUNTER)??0)+1; scoped.store.set(COUNTER,next); scoped.emit('docs:lab:counter',{value:next,source:'React'}); } }catch(error){if(alive.current)setStatus(tr("No se pudo completar: {0}", [error.message]));} }; node.addEventListener('wu-command-intent',handle); return ()=>node.removeEventListener('wu-command-intent',handle); },[draft,result.command,result.error,counter,status,scoped]); return React.createElement('wu-docs-command-workbench',{ref:element}); } export function register(wu) { let root=null; wu.define('command-lab',{ mount(container,{wu:scoped}) { if(root)throw new Error(tr("command-lab ya está montado")); diagnostics.mounts+=1; root=createRoot(container); flushSync(()=>root.render(React.createElement(CommandLab,{scoped}))); scoped.emit('docs:lab:lifecycle',{app:'command-lab',phase:'mount',framework:'React'}); }, unmount(_container,{wu:scoped}) { root?.unmount();root=null;diagnostics.unmounts+=1; scoped.emit('docs:lab:lifecycle',{app:'command-lab',phase:'unmount',listeners:diagnostics.listeners}); }, }); }