> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/contributor/contributor-pt/guias-para-colaboradores/well-known-components/components.md).

# Components

Components são peças de software autocontidas, concebidas como caixas-pretas que recebem outros components (ou nenhum) para executar as suas tarefas. O objetivo principal é desacoplar secções de código e maximizar a testabilidade.

## Estrutura de diretórios

Todos os components DEVEM ser definidos dentro de um diretório dedicado contendo pelo menos estes quatro ficheiros:

* `component.ts` - Contém o código de implementação do component
* `types.ts` - Contém a interface do component e os types expostos
* `errors.ts` - Contém todas as classes de erro exportadas
* `index.ts` - Exporta a API pública do component

### Estrutura de exemplo

```
src/
└── components/
    └── my-component/
        ├── component.ts
        ├── types.ts
        ├── errors.ts
        └── index.ts
```

## Ficheiro de tipos

Os Components seguem uma interface que define a sua API pública. Esta interface pode ser partilhada entre components intercambiáveis ou usada para compreender os métodos expostos pelo component.

Todos os components que tenham a sua própria interface DEVEM defini-la num `types.ts` ficheiro dentro do diretório do component.

Outros types expostos pelo component TAMBÉM DEVEM ser colocados neste ficheiro.

### Exemplo: `types.ts`

```tsx
export type Something = {
  aValue: boolean
  anotherValue: string
}

export interface IMyComponent {
  myFunction: () => boolean
  getSomething: () => Something
}
```

### Tipos partilhados

Tipos partilhados entre vários components, como interfaces comuns, DEVEM ser colocados num `types.ts` ficheiro no diretório raiz do código-fonte do projeto (`/src/types.ts`).

## Ficheiro do component

O ficheiro do component contém a função criadora do component. Esta função segue uma convenção específica de nomeação e estrutura.

### Convenção de nomeação

As funções criadoras de components DEVEM ser nomeadas como: `create` + `ComponentName` + `Component`

**Exemplo:** `createMyNewComponent`

### Assinatura da função

A função criadora DEVE:

1. Receber um objeto components como primeiro parâmetro contendo todas as dependências
2. Receber opcionalmente parâmetros de configuração adicionais
3. Retornar um objeto contendo os métodos expostos (públicos)

### Estrutura do Component

No início da função criadora do component:

1. Extrair as dependências do objeto components
2. Inicializar variáveis comuns (ex.: loggers, configuração)
3. Definir funções auxiliares internas
4. Definir métodos públicos
5. Retornar a API pública

### Exemplo: `component.ts`

```tsx
import { IMyComponent, Something } from './types'
import { WrongStringError } from './errors'

export function createMyNewComponent(
  components: Pick<AppComponents, 'logs'>
): IMyComponent {
  const { logs } = components
  const logger = logs.getLogger('my-component')

  // Método interno - não exposto
  function computeString(fstString: string, sndString: string): string {
    if (fstString.length === 0) {
      throw new WrongStringError()
    }
    
    return fstString + ' ' + sndString
  }

  // Método público - exposto no objeto retornado
  function myFunction(): boolean {
    return true
  }

  // Método público - exposto no objeto retornado
  function getSomething(): Something {
    logger.info('Getting something')
    
    return {
      aValue: true,
      anotherValue: computeString('aString', 'anotherString')
    }
  }

  // Retornar a API pública
  return {
    myFunction,
    getSomething
  }
}
```

## Ficheiro de erros

O ficheiro de erros contém classes de erro personalizadas que um component pode lançar. Estes erros podem ser usados noutros components ou controladores para identificar e tratar corretamente condições de erro específicas.

### Exemplo: `errors.ts`

```tsx
export class WrongStringError extends Error {
  constructor(message?: string) {
    super(message || 'Incorrect String')
    this.name = 'WrongStringError'
  }
}

export class ComponentNotInitializedError extends Error {
  constructor() {
    super('Component has not been initialized')
    this.name = 'ComponentNotInitializedError'
  }
}
```

### Melhores práticas de tratamento de erros

* Criar classes de erro específicas para diferentes condições de erro
* Incluir mensagens de erro significativas
* Defina o `name` propriedade para corresponder ao nome da classe para facilitar a depuração
* Documentar quais erros podem ser lançados por cada método público

## Ficheiro de índice

O ficheiro de índice serve como ponto de entrada público para o component, exportando apenas o que deve estar acessível a outras partes da aplicação.

### Exemplo: `index.ts`

```tsx
export { createMyNewComponent } from './component'
export type { IMyComponent, Something } from './types'
export { WrongStringError } from './errors'
```

## Melhores práticas

1. **Responsabilidade única** - Cada component deve ter um único propósito claro
2. **Dependências explícitas** - Todas as dependências devem ser injetadas através do parâmetro components
3. **Imutabilidade** - Preferir estruturas de dados imutáveis sempre que possível
4. **Tratamento de erros** - Usar classes de erro personalizadas para diferentes condições de erro
5. **Registo** - Usar o logger para depuração e monitorização
6. **Segurança de tipos** - Aproveitar ao máximo o sistema de tipos do TypeScript
7. **Documentação** - Documentar métodos complexos e lógica de negócio

## Ciclo de vida do component

Alguns components podem precisar de executar operações de configuração ou limpeza. WKC fornece métodos de ciclo de vida:

* `[START_COMPONENT]` - Chamado quando o component inicia
* `[STOP_COMPONENT]` - Chamado quando o component para

Veja a [Adaptadores](/contributor/contributor-pt/guias-para-colaboradores/well-known-components/adapters.md) secção para exemplos de components que usam métodos de ciclo de vida.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/contributor/contributor-pt/guias-para-colaboradores/well-known-components/components.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
