Apps remotas e portas de capacidades
Conecte uma app de outra origem por iframe e MessagePort com permissões e revogação.
Esta página descreve o WU Framework 4.0.0. Consulte o guia de migração para Framework 4.0 e CLI 1.2 antes de atualizar um projeto existente.
Configurar o host
import { wu } from 'wu-framework/core';
import 'wu-framework/ports';
await wu.init({ apps: [{
name: 'widget', url: 'https://widgets.example/app/', sandbox: 'remote',
manifest: { entry: 'index.html', wu: { permissions: ['events.emit:widget:*'] } },
grants: ['events.emit:widget:*'],
iframe: { title: 'Remote widget', timeout: 15000, callTimeout: 10000 },
}] });
await wu.mount('widget', '#widget-slot');
await wu.update('widget', { theme: 'light' });
Crie #widget-slot no shell e sirva a app na origem configurada. WU cria o iframe e transfere a porta para a origem exata da URL. O navegador aplica o isolamento entre origens; as mensagens executam pela facade de widget, com as permissões solicitadas e concedidas.
Conectar o documento remoto
import { connect } from 'wu-framework/remote';
const remote = await connect({ hostOrigin: 'https://shell.example' });
const off = remote.onProps(props => {
document.documentElement.dataset.theme = props.theme;
});
await remote.emit('widget:ready', { ready: true });
await remote.resize(document.body.scrollHeight);
window.addEventListener('pagehide', () => {
off();
remote.close();
}, { once: true });
O documento remoto usa seu próprio renderer e deve aceitar apenas a origem real do shell em hostOrigin. Chamadas ao host são assíncronas: aguarde store.get, store.set, emit e RPC. onProps recebe atualizações; props mantém os últimos valores. resize solicita uma altura e whenClosed observa o fechamento. Os dados devem suportar structured clone.
O iframe usa allow-scripts allow-same-origin allow-forms por padrão; configure com iframe.sandbox e iframe.allow. wu.remoteOf(name) retorna sua janela. hide preserva o iframe; unmount o remove e revoga a porta. Falhas de conexão são WU_REMOTE_TIMEOUT e WU_REMOTE_LOAD_FAILED; um handler remoto que excede o prazo produz WU_PORT_CALL_TIMEOUT.
Cabeçalhos das duas origens
{ "security": { "frameOrigins": ["https://widgets.example"] } }
Na WU CLI 1.0.0, security.frameOrigins adiciona essas origens a frame-src, não a script-src nem a connect-src. A resposta remota deve permitir o shell em frame-ancestors e não bloqueá-lo com X-Frame-Options. Configure também o renderer e a entrada wu-framework/remote no build remoto.
Criar uma porta manualmente
const capability = await wu.ports.mint('widget', { props: { theme: 'dark' } });
worker.postMessage({ wu: 1, type: 'port', app: 'widget' }, [capability.port]);
await capability.ready;
capability.push({ theme: 'light' });
capability.close('finished');
const active = wu.ports.list();
const revoked = wu.ports.revoke('widget');
O host cria worker e registra previamente widget com grants; o receptor precisa conectar o protocolo remoto. A porta pode ser transferida e fechada. close revoga essa porta; revoke fecha as portas da app. Chamadas pendentes rejeitam com WU_PORT_CLOSED. A comunicação por mensagens não compartilha diretamente o objeto store entre documentos.
Validação de origem no 4.0
connect(options) e waitForPort(options) exigem hostOrigin; omiti-lo produz WU_REMOTE_HOST_ORIGIN_REQUIRED. "*" aceita conscientemente qualquer origem. Em iframe ou popup, o emissor também deve ser parent ou opener; source permite indicar outra janela. O overload connect(port) aceita uma porta já recebida.
A origem da app é a origem de sua url. Um entry em outra origem falha com WU_REMOTE_ORIGIN_MISMATCH. Um remoto na origem do shell falha com WU_REMOTE_SAME_ORIGIN, salvo com iframe.allowSameOrigin: true; essa exceção perde o isolamento entre origens. wu.detach() rejeita remotos com WU_WINDOW_REMOTE_UNSUPPORTED.
O host continua oferecendo a porta após load até receber resposta, permitindo que o remoto aguarde trabalho antes de conectar. Pela porta, consume() permite apenas métodos da shape declarada; sem shape, exclui métodos de Object.prototype. O unmount e destroy() revogam as portas do core.