> For the complete documentation index, see [llms.txt](https://docs.skail.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skail.dev/referencia/sdk-typescript-e-outras-linguagens.md).

# SDKs e linguagens

Os fluxos do skail são escritos com o SDK da sua linguagem: hoje C# (.NET) e TypeScript, com Java, Python e outras linguagens a caminho.

Quem inicia um fluxo ou dispara um evento pode estar em qualquer linguagem, pela API HTTP.

<figure><img src="https://1898946878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsJmS5ILPG5x2x5j0WyiV%2Fuploads%2FHp8xP1Drf3hBfC0N59Z2%2Fap-sdk-linguagens.svg?alt=media" alt="À esquerda, em qualquer linguagem, o job que inicia chama POST /trigger, e o front-end que aprova e o webhook que confirma chamam POST /api/v1/fire no skail. À direita, a sua aplicação escrita com o SDK: o host, configurado pelas variáveis SKAIL_*, busca trabalho no skail, e a function orquestra o fluxo com commands para operações de I/O, com retry e resultado gravado, e esperas duráveis por tempo ou evento externo."><figcaption></figcaption></figure>

## Hoje

O SDK é o pacote que permite escrever functions e commands duráveis. O modelo é o mesmo em todas as linguagens:

* uma function orquestra o fluxo;
* cada operação de I/O fica em um command com retry e resultado gravado;
* as esperas por tempo e por evento externo são duráveis.

Os exemplos desta documentação, inclusive o [Quickstart](/comece-aqui/quickstart.md), aparecem em abas, uma por linguagem.

| Linguagem  | Pacotes                                                         | Requisito          |
| ---------- | --------------------------------------------------------------- | ------------------ |
| C#         | `Skail.Platform.Runtime`                                        | .NET 8 ou superior |
| TypeScript | `@skail/runtime` e `@skail/build`; `@skail/testing` para testes | Node.js            |

## Como rodar

Em todas as linguagens a aplicação tem classes com functions e commands e um host, que fica em execução buscando trabalho no skail, configurado pelas variáveis `SKAIL_*`. O que muda é como o runtime conhece os métodos: em C#, pelo registro no host; em TypeScript, pelo manifest que o `skail build` gera.

{% tabs %}
{% tab title="C#" %}
Uma aplicação .NET com o pacote `Skail.Platform.Runtime`. O atributo de assembly expõe as functions e os commands ao runtime, e `UseSkail()` registra o runtime no host:

{% code lineNumbers="true" %}

```csharp
// Program.cs
using Microsoft.Extensions.Hosting;
using Skail.Platform.Runtime.Hosting;
using Skail.Platform.Runtime.Standard;

[assembly: VisibleToSkailPlatform]

var builder = Host.CreateApplicationBuilder(args);
builder.UseSkail();

await builder.Build().RunAsync();
```

{% endcode %}

A referência está em [Configuração do host](/referencia/sdk-csharp/configuracao-do-host.md), e a referência completa do SDK, em [Construir, SDK .NET](/referencia/sdk-csharp.md).
{% endtab %}

{% tab title="TypeScript" %}
Um entry point exporta as classes com `@SkailFunction` e `@SkailCommand` (e, se preciso, `providers`), o build gera o bundle e o manifest do workload, e o host carrega o bundle.

O entry point:

{% code lineNumbers="true" %}

```typescript
// src/entries/app.ts
export { MinhaFuncao } from "../minha-funcao.js";
```

{% endcode %}

O build, que gera o bundle e o manifest do workload:

```bash
# build: gera o bundle e o manifest do workload
node_modules/.bin/skail build src/entries/app.ts --workload meu-workload:1.0.0 \
  --out .skail/app/skail-functions.mjs --manifest .skail/app/manifest.json
```

O host, que carrega o bundle e executa as functions e os commands:

{% code lineNumbers="true" %}

```typescript
// src/main.ts
import { createSkailPlatform } from "@skail/runtime";

const controller = new AbortController();
for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, () => controller.abort());

const platform = createSkailPlatform({
  workload: "meu-workload:1.0.0",
  bundle: new URL("../.skail/app/skail-functions.mjs", import.meta.url),
  manifest: new URL("../.skail/app/manifest.json", import.meta.url),
  sidecar: { baseUrl: process.env.SKAIL_SIDECAR_URL ?? "http://127.0.0.1:5450", namespace: process.env.SKAIL_NAMESPACE ?? "demo-org" },
});
await platform.run(controller.signal);
```

{% endcode %}

A referência do host está em [Configuração do host](/referencia/sdk-csharp/configuracao-do-host.md).
{% endtab %}
{% endtabs %}

## Regras do SDK

As regras de fundo valem para todas as linguagens e estão em [Modelo de programação](/construa/conceitos/functions-e-commands.md) e [Determinismo e replay](/construa/conceitos/replay-e-determinismo.md). O que cada SDK pede no código:

{% tabs %}
{% tab title="C#" %}

* Functions e commands são métodos `public`, de instância e `async`, com `[SkailFunction]` e `[SkailCommand]`, e retornam `SkailTask` ou `SkailTask<T>`.
* `SkailTask.WhenAny` devolve a espera que terminou primeiro; o prazo vencido é testado comparando o resultado com a espera do delay.
* Dentro de uma function, `DateTime.UtcNow`, `Guid.NewGuid()`, `Random`, `Task.Delay` e `Task.WhenAll` compilam, mas quebram o replay: o que não é determinístico vai para um command.
* As classes são registradas no contêiner de injeção de dependência por `UseSkail()`, e as dependências entram pelo construtor.
  {% endtab %}

{% tab title="TypeScript" %}

* Functions e commands são métodos públicos, de instância e `async`, com `@SkailFunction()` e `@SkailCommand()`, e retornam `Promise<T>`; o `skail build` rejeita métodos `static`, `private` ou sem `async`.
* `Skail.whenAny` resolve com o valor de quem terminou primeiro, e o delay resolve `undefined`. Por isso o prazo vencido é testado com `=== undefined`, e o payload do evento não pode ser `undefined`.
* Dentro de uma function, `new Date()` sem argumento, `Date.now()`, `Math.random()`, `crypto.randomUUID()`, `setTimeout()` e `fetch()` lançam erro: o que não é determinístico vai para um command.
* O runtime não infere parâmetros de construtor: as dependências são ligadas por `providers` (`useFactory`) ou instanciadas na classe.
  {% endtab %}
  {% endtabs %}

## Em breve

Java, Python e outras linguagens.

## Qualquer linguagem pela API HTTP

Ter ou não SDK não impede que um sistema participe dos fluxos. Iniciar uma function e disparar um evento são dois `POST` na API HTTP, de qualquer stack. Na prática, um fluxo típico tem o orquestrador escrito com o SDK e os sistemas que iniciam o fluxo e disparam eventos (o front-end que aprova, o webhook que confirma, o job que inicia) em qualquer linguagem. [Chamar o skail de qualquer linguagem por REST](/construa/como-fazer/chamar-o-skail-de-qualquer-linguagem-por-rest.md) mostra como.

## Próximos passos

[Quickstart](/comece-aqui/quickstart.md) para rodar o primeiro fluxo. [Chamar o skail de qualquer linguagem por REST](/construa/como-fazer/chamar-o-skail-de-qualquer-linguagem-por-rest.md) e a referência de [POST /trigger](/referencia/api-http/post-trigger.md) e [POST /api/v1/fire](/referencia/api-http/post-fire.md).
