Web Components (view.component)
Uma entrada view.component descreve um custom element reutilizável (web component) que o Web Host pode descobrir, injetar e registrar automaticamente. Diferente de uma página, um componente não tem iframe próprio — ele é uma tag HTML customizada que pode aparecer em qualquer lugar onde o template de uma página ou do host o coloque.
Para orientações sobre como escrever a implementação do componente, veja Web Component.
Campos de Frontend (bloco wippy do package.json)
Esses campos são escritos pelo desenvolvedor de FE no bloco wippy do package.json. O plugin do vite os embute em wippy-meta.json em tempo de build, e o wippy/views os lê de lá como padrões.
Todos os campos desta seção podem ser sobrescritos pelo operador no
_index.yaml. O YAML sempre tem precedência.
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
type |
string | — | Deve ser "component" ou "widget"; "widget" é a convenção do template |
tagName |
string | — | Nome do custom element; deve conter um hífen conforme a especificação HTML |
props |
object | — | JSON Schema descrevendo os atributos aceitos pelo componente |
events |
object | — | JSON Schema descrevendo os eventos DOM customizados que o componente emite |
wippy.type no package.json
Pacotes de web component definem "type": "widget" ou "type": "component" (não "page") dentro do seu bloco wippy. O app-template usa atualmente "widget", e o plugin do vite aceita ambos os nomes de componente para este contrato de runtime.
{
"specification": "wippy-component-1.0",
"wippy": {
"tagName": "example-reaction-bar",
"type": "widget",
"props": { ... },
"events": { ... }
}
}
Em tempo de deploy, o meta.tag_name do YAML do operador é autoritativo e sobrescreve o valor empacotado; wippy.tagName (embutido em wippy-meta.json a partir do package.json) é apenas o fallback que o wippy/views usa quando a entrada YAML omite tag_name (ordem de resolução: meta.tag_name do YAML → wippy.tagName empacotado). Mantenha os dois em sincronia para evitar surpresas, mas o YAML vence se divergirem.
Schema de Props
A chave wippy.props no package.json é um objeto JSON Schema descrevendo os atributos aceitos pelo componente. O plugin do vite o inclui em wippy-meta.json, e o Web Host o usa ao expor metadados do componente para consumidores como o renderizador de artefatos do chat e o sanitizador de tags (que precisa saber quais atributos são legítimos para não removê-los).
{
"wippy": {
"props": {
"type": "object",
"properties": {
"reactions": {
"type": "array",
"items": { "type": "string" },
"default": ["👍", "👎", "❤️", "🎉", "🤔"],
"description": "Array of emoji reactions to display"
},
"allow-multiple": {
"type": "boolean",
"default": false,
"description": "Whether multiple reactions can be active simultaneously"
}
}
}
}
}
Nomes de atributos em properties seguem a convenção de atributos HTML (kebab-case). Os valores default do schema também são aplicados em tempo de execução pelo parser de props do web component quando um atributo está ausente.
Schema de Eventos
A chave wippy.events espelha o formato de props, mas descreve os eventos DOM customizados que o componente emite via useEvents(). Cada chave é um nome de evento; o valor é um JSON Schema para o payload de detail do evento.
{
"wippy": {
"events": {
"type": "object",
"properties": {
"reaction": {
"type": "object",
"properties": {
"emoji": { "type": "string" },
"count": { "type": "number" },
"active": { "type": "boolean" }
},
"description": "Fired when a reaction is toggled"
}
}
}
}
}
O sanitizador de mensagens de chat do Web Host coloca em allowlist os atributos de componente vindos de props.properties no wippy-meta.json. Schemas de eventos documentam os eventos customizados emitidos para ferramentas e consumidores; eles não são usados para permitir atributos de listener de evento DOM através do conteúdo de chat sanitizado.
Configuração do Operador (_index.yaml)
Esses campos são definidos pelo operador no bloco meta da entrada de registry _index.yaml. A maioria representa política pura de deploy — roteamento, controle de acesso e servir arquivos — que só faz sentido em tempo de deploy e não tem superfície de autoria no package.json (announced, secure, url, auto_register). Dois campos, tag_name e entry_point, são diferentes: eles são escritos pelo FE no package.json (embutidos em wippy-meta.json) e as chaves YAML são apenas sobrescritas opcionais por deploy desses valores empacotados.
announced,secure,urleauto_registersão política pura de deploy e não podem ser definidos no package.json — eles são definidos pelo operador para cada ambiente.tag_nameeentry_pointsão padrões escritos pelo FE que o operador pode sobrescrever no YAML.
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
tag_name |
string | wippy.tagName |
Escrito pelo FE como wippy.tagName no package.json (obrigatório pelo plugin do vite); a chave YAML sobrescreve o valor empacotado. Nome do custom element; deve conter um hífen conforme a especificação HTML |
announced |
boolean | false |
Deve ser true para o componente aparecer em /api/public/components/list. Recorre a meta.public se este estiver definido. |
auto_register |
boolean | false |
true → o Web Host carrega e registra o componente automaticamente na inicialização |
secure |
boolean | false |
Exige autenticação |
url |
string | — | Caminho de mount estático para o bundle compilado do componente |
base_path |
string | "" |
Subcaminho opcional anexado a url para formar a raiz do projeto; a URL resolvida do bundle é composta como <url>/<base_path>/<entry_point>. Respeitado de forma idêntica às páginas, embora as entradas de componente atuais do app-template o omitam |
entry_point |
string | wippy.browser → index.js |
Escrito pelo FE como o campo browser de nível superior no package.json (embutido em wippy-meta.json); a chave YAML sobrescreve o valor empacotado, recorrendo a index.js. Arquivo do módulo de entrada; o host o injeta como um <script type="module"> |
Uma entrada mínima se parece com isto:
- name: reaction-bar
kind: registry.entry
meta:
type: view.component
name: reaction-bar
tag_name: example-reaction-bar
announced: true
secure: false
auto_register: true
url: /app/wc/reaction-bar
entry_point: index.js
Os Três Portões para o Autoload
Para que o Web Host carregue automaticamente um componente, as três condições precisam valer simultaneamente:
-
announced: true— owippy/viewsfiltra por essa flag no lado do servidor emlist_components.lua. Não existe parâmetro de query para contorná-la. Um componente comannounced: falsenunca aparece em/api/public/components/list, independentemente de qualquer outra configuração. -
auto_register: true— a funçãoloadGlobalAutoloadWidgetsdo host consulta o endpoint de listagem com?auto_register=true. Componentes sem essa flag são excluídos dessa resposta filtrada. -
A tag ainda não está registrada — antes de injetar o script, o host verifica
customElements.get(tagName). Se a tag já estiver definida (por exemplo, de uma navegação anterior), o host pula a injeção para evitar definição dupla.
Se qualquer portão faltar, o componente fica silenciosamente ausente. Para verificar: curl /api/public/components/list?auto_register=true — sua tag precisa aparecer na resposta.
A Sequência de Autoload
Quando uma página dentro do Web Host termina de montar, o host executa a seguinte sequência:
-
GET /api/public/components/list?auto_register=true— busca todos os componentes anunciados que se auto-registram. -
Para cada componente cujo
customElements.get(tagName)éundefined, o host adiciona adocument.head:<script type="module" src="/app/wc/reaction-bar/index.js?declare-tag=example-reaction-bar"></script>O parâmetro de query
?declare-tag=é o canal que diz ao chunk de entrada sob qual nome de custom element se registrar. -
O chunk de entrada chama
define(import.meta.url, ElementClass). Autores de componentes importamdefinede@wippy-fe/webcomponent-vue(ou@wippy-fe/webcomponent-core), que reexportam odefinedo proxy; em tempo de execução o import map o resolve para a única instância de@wippy-fe/proxy. O helperdefinelênew URL(import.meta.url).searchParams.get('declare-tag')e chamacustomElements.define(tagName, ElementClass). -
O Vue (ou qualquer framework) renderiza um elemento
<example-reaction-bar>. O navegador faz o upgrade do elemento,connectedCallbackdispara, eWippyVueElementmonta seu app Vue dentro de um shadow root.
Por Que auto_register: false É Útil
Definir auto_register: false exclui o componente da varredura global de autoload. Isso é apropriado quando:
- O componente é grande e deve carregar apenas nas páginas que explicitamente precisam dele.
- O componente é registrado programaticamente via
loadByTagName('example-heavy-chart')(importado de@wippy-fe/proxy) no ponto de chamada. - O componente é um bloco de construção interno usado apenas dentro de outro bundle, não como um custom element autônomo.
import { loadByTagName } from '@wippy-fe/proxy'
await loadByTagName('example-heavy-chart')
O registro tardio mantém o carregamento inicial da página leve. O componente ainda precisa de announced: true para que loadByTagName() o resolva através da API — o endpoint GET /components/by-tag/{tag} retorna 404 "Component is not announced" quando a flag é false.