@loom-forge/runtime
v0.3.1
Published
loom-forge · o RUNTIME de um app React: o motor montado com o binder do TSLite, os planners e os renderers default, e o boundary de estado. Um install, uma versão, uma montagem.
Downloads
799
Maintainers
Readme
@loom-forge/runtime
O motor montado. Um install, uma versão de cada peça, e uma montagem — a que todo app React sobre o loom-forge faz igual. Este package não tem algoritmo: o que ele traz é o conjunto e o default.
pnpm add @loom-forge/runtime reactOs @tslite/* do tslite e do forge são peer (ADR-021): a aplicação fornece uma instância do TSLite, a mesma para todo repo que a compõe. npm 7+ e pnpm 8+ os instalam sozinhos.
import { createRuntime, ForgeProvider, ForgeView } from "@loom-forge/runtime";
const runtime = createRuntime({
registry: [
["Card", Card, { schema }],
["Field", Field, fieldDescriptor],
],
defs: [userCard], // os componentes declarados em JSON
actions: port, // o `ActionPort` do host (o Tier 0 do contrato de actions)
onActionResult: (id, result) => {
if (!result.success) toast(result.error?.code);
},
});
<ForgeProvider forge={runtime}>
<ForgeView node={page} data={data} contexts={contexts} />
</ForgeProvider>;Por que ele existe
Não é o número de install. São duas coisas:
Uma fronteira de dependência que nenhuma das duas pontas pode cruzar. O
forge-react não pode depender do
tslite — arrastaria a linguagem inteira para quem trocou o binder, e o
port BindingEngine, que existe para o binder ser trocável, viraria enfeite. E o tslite não
pode depender do forge-react: ele é o adapter da linguagem, e não conhece view. O conjunto só
pode ser um terceiro.
E uma falha silenciosa. O default do compositor é o identityBinder. Um motor montado sem o
binder do TSLite trata {{ props.x }} como a string "{{ props.x }}": nada lança, nada
avisa, e a tela mostra a chave. Há um teste aqui que crava os dois lados — o mesmo documento, com
e sem a montagem.
createRuntime(options)
Devolve o Forge do forge-react, montado. É o createForge com a
montagem decidida, não um motor diferente — tudo tem override.
| opção | default | o quê |
| ------------------------------ | ---------------------- | --------------------------------------------------------- |
| registry | — | as peças: [type, componente, descriptor?] |
| defs | — | os componentes em JSON; entram compilados, uma vez |
| actions | — | o ActionPort do host |
| onActionResult | aviso em dev na falha | recebe todo envelope que voltou |
| binder | createTsliteBinder() | a linguagem. Trocar o perfil é montar o binder e passá-lo |
| planners / layoutRenderers | os do compositor | mapas name → planner/renderer |
| e o resto do createForge | — | resolver, capabilities, requireEntryRoot, inspect |
[!WARNING] Passe o
onActionResult. O envelope tem dois consumidores: o documento, pela cadeiathen/catchque ele declarou, e o host, sempre. Sem ouvinte, uma falha de domínio vira aviso em dev e desaparece em produção.
O que NÃO entra na montagem: data, contexts e commands. Os três são dado de render —
mudam com o mundo, e o lugar deles é o <ForgeView>. Congelá-los aqui fixaria dado num artefato
do relógio lento.
O contexto pode entrar como STORE. Quem tem estado vivo passa contextStore={…}
(createContextStore do core) em vez de contexts={…}: cada seção assina os nomes que declara,
e publicar um contexto não visita quem não o lê (ADR-023 do repo). Com valores, a granularidade
vem da projeção estável — as duas formas valem, e a semântica é a mesma.
O conjunto
| package | o quê |
| ----------------------------------------- | ----------------------------------------------- |
| core | o kernel headless e os ports |
| react | a view: registry de componentes e os renderers |
| tslite | a linguagem: {{ }} compilado e o bind gateado |
| forge | o construtor: IR, grafo, regras, estado |
| forge-react | a view do construtor e o boundary de estado |
O modelo, a análise e a view saem flat deste package. Da linguagem sai o que se monta —
createTsliteBinder, DEFAULT_PROFILE —; a fase de compilação (compile, os diagnósticos, o
addressOf da árvore) fica no @loom-forge/tslite, que continua sendo um package: quem consolida
no servidor importa de lá e não carrega o executor.
Fora do conjunto, e por motivos diferentes:
checkelanguage-service— outro relógio. Tipo é autoria e CI, nunca o hot path de render (ADR-206 docheck), e eles arrastam o@tslite/checker. Instale comodevDependency;eject— traduz a definição para TSX; é ferramenta, não runtime;grid— tem peer próprio (react-grid-layout). Entra quando houver dashboard:planners/layoutRendererssão opções docreateRuntime;editoreaddress— são de quem edita o documento, e cada um tem peer próprio.
Licença
MIT © Anderson D. Rosa
