Andrade Systems
Em desenvolvimentoFiveM

triad-ui

Shell de interface · Solid e TypeScript

Painéis são desmontados quando deixam de ficar visíveis, por regra da própria estrutura.

TypeScript
621 linhas
Lua da ponte
227 linhas
Runtime
Solid

decisão registrada, medida com cliente real

Bundle contra React
7,4× menor

comprimido, medido no build de produção

Fonte verificada no repositório interno em 08/09/2026

O que faz

Em uso

Este resource não é uma interface — é o ponto de montagem. Ele liga a ponte com o jogo, liga o ciclo de vida e registra painéis. As interfaces definitivas são construídas separadamente, sobre estes contratos.

A regra que ele existe para garantir é uma só: um painel só é montado quando fica visível, e é desmontado quando some. Componente montado e invisível continua assinando evento, animando e recebendo estado — o benchmark mediu os três candidatos fazendo exatamente isso depois de escondidos, cada um a seu ritmo, porque nada os impedia.

O harness de desenvolvimento permite construir e ver a interface num navegador comum, sem abrir o jogo. Ele deliberadamente não simula o servidor: a resposta é sempre erro, porque harness que responde sucesso ensina a interface a confiar em resposta que não veio.

Evidência

Como o sistema aparece

Capturas da interface real, renderizada com payload de demonstração derivado dos contratos do resource — organizações, cargos, pessoas e identificadores são sintéticos. Onde não existe interface, entra visualização técnica, rotulada como tal.

  • Visualização técnica

    O ciclo de vida de um painel. A shell não tem componente visual próprio — por isso não há captura de interface aqui.

Por dentro da engenharia

Decisões de implementação

Um bloco por decisão de implementação. Abra o que interessa.

Três critérios eliminatórios, e nenhum eliminou ninguém

Problema

A escolha do runtime de interface tinha três critérios declarados eliminatórios: impacto no quadro do jogo, custo zero quando oculta, e memória por contexto. Decidir por moda era explicitamente proibido.

Solução

A medição com cliente real mostrou os três candidatos dentro do ruído no impacto de quadro; a métrica de "custo zero quando oculta" era inaplicável como escrita, porque a própria sonda mantinha vivo o mecanismo que media; e a memória deu o mesmo valor nos três, porque o que se mediu foi o heap do processo inteiro. Os três critérios saíram, e a decisão caiu nos secundários.

Por que foi feito assim

Registrar que o critério principal não decidiu é mais honesto — e mais útil para quem revisar depois — do que forjar uma diferença onde a medição não encontrou nenhuma.

O que de fato diferiu, e por qual mecanismo

Problema

Sem os eliminatórios, sobrou comparar o que realmente separava os candidatos, sem transformar ruído em ordenação.

Solução

Tamanho e inicialização: 7,4× menor comprimido e metade do tempo para subir, com mecanismo esperado — menos código para baixar e interpretar. Estratégia de atualização: o vencedor faz praticamente uma mutação de DOM por atualização, contra duas do segundo colocado; o terceiro agrupa e tem o menor total absoluto, vantagem que se dissolve quando a origem limita frequência, como uma interface de cidade precisa fazer de qualquer forma.

Por que foi feito assim

Bundle é determinístico e o processo de build falha se divergir do commitado. Os números de quadro eram ruído nos três e não foram usados para ordenar nada.

O contrapeso comercial, dito por extenso

Problema

O runtime escolhido é de nicho, e o framework será vendido. Quem compra vai querer mexer na interface — e a interface não é protegível pelo mecanismo de escrow da plataforma: o comprador enxerga e edita esse código.

Solução

A decisão foi aceita assumindo que a superfície que o comprador toca é o sistema de design e os componentes, não o runtime — e que essa superfície precisa ser documentada com esse público em mente.

Por que foi feito assim

É risco comercial real e não aparece em benchmark nenhum. Está escrito junto com o que reverteria a decisão, para que a revisão futura tenha por onde começar.

Decisões

Decisões e trade-offs

Cada decisão registra a justificativa e o trade-off aceito.

  1. Solid como runtime da interface em jogo.

    Com os eliminatórios empatados, a diferença nos secundários não é marginal: 7,4× em bundle comprimido, metade do tempo de inicialização, 8× na pintura de abertura e atualização praticamente um para um com o DOM.

    Custo aceito · Ecossistema menor e menos gente contratável do que a alternativa mais popular — e isso importa porque o framework será vendido e suportado. Se na prática o comprador tiver de escrever código idiomático do runtime para customizar, a premissa cai e a decisão volta à mesa.

  2. A shell não contém nenhum componente visual.

    Separar montagem de desenho é o que permite construir as interfaces definitivas em cima dos contratos, sem que o ciclo de vida dependa de como cada tela foi escrita.

    Custo aceito · Não existe nada para mostrar visualmente neste resource — é por isso que a evidência aqui é diagrama, e não captura de tela.

Stack

O que foi usado

  • Interface

    • Solid 1.9
    • TypeScript
    • Vite
  • Ponte

    • Lua 5.4
    • Contratos tipados de mensagem
    • Ciclo de vida por visibilidade
  • Desenvolvimento

    • Harness que roda em navegador comum
    • Sai do pacote de produção no build