npm package: @statedelta-actions/sdk
Description: Barrel package — re-exports all @statedelta-actions packages with synchronized versions
Author: Anderson D. Rosa
Latest version: 0.3.0

# @statedelta-actions/sdk

> Ponto de entrada unificado para o ecossistema `@statedelta-actions`.
> Uma dependência, todos os packages, versões sincronizadas.

---

## Table of Contents

1. [Filosofia](#filosofia)
2. [Instalação](#instalação)
3. [Quick Start — Full Stack](#quick-start--full-stack)
4. [Os 4 Componentes](#os-4-componentes)
5. [Composição — Como Tudo se Conecta](#composição--como-tudo-se-conecta)
6. [Dois Modos de Import](#dois-modos-de-import)
7. [Packages Incluídos](#packages-incluídos)
8. [Três Modos de Operação](#três-modos-de-operação)
9. [Por que usar o SDK](#por-que-usar-o-sdk)
10. [Documentação dos Packages](#documentação-dos-packages)
11. [Licença](#licença)

---

## Filosofia

O `@statedelta-actions` é um sistema de execução declarativa. Ações são objetos JS com diretivas. Handlers dão significado às diretivas. O engine orquestra execução. O analyzer observa e valida.

O SDK não é um framework. É um **kit de composição**. O consumer monta o sistema que precisa:

- Só precisa de actions? Use o engine.
- Quer análise estática? Adicione o analyzer.
- Precisa de triggers condicionais? Adicione rules.
- Quer event-driven? Adicione events.
- Quer tudo junto com versões garantidas? Use o SDK.

Cada componente funciona sozinho. Nenhum assume a existência dos outros. O consumer é quem decide a composição e faz o wiring.

### Três metáforas

| Componente | Metáfora | Papel |
|-----------|----------|-------|
| **ActionEngine** | V8 | Runtime puro — executa diretivas |
| **ActionAnalyzer** | TypeScript | Análise estática — observa, valida, consulta |
| **RuleEngine** | Cron | Triggers condicionais — `when() → invoke()` |
| **EventProcessor** | EventEmitter | Dispatch de listeners — `on(event) → invoke()` |

O engine nunca analisa. O analyzer nunca muta. O RuleEngine nunca executa diretivas (delega pro engine). O EventProcessor é o mesmo — registro de listeners como hidden actions, dispatch via engine.

---

## Instalação

```bash
pnpm add @statedelta-actions/sdk
```

---

## Quick Start — Full Stack

O setup completo: engine processa diretivas, analyzer observa o grafo, rules avaliam triggers, events despacham listeners.

```typescript
import {
  createActionEngine,
  createActionAnalyzer,
  createRuleEngine,
  createEventProcessor,
} from "@statedelta-actions/sdk";
import { HALT_HANDLER } from "@statedelta-actions/sdk/rules";

// ── 1. Handlers — dão significado aos tipos de diretiva ──

const handlers = {
  state: {
    analyze: () => ({ capabilities: ["write"], dependencies: [] }),
    execute: (directive, frame) => {
      frame.ctx[directive.target] = directive.value;
      return { ok: true, data: directive.value };
    },
  },
  emit: {
    analyze: () => ({ capabilities: ["emit"], dependencies: [] }),
    execute: (directive, frame) => {
      frame.ctx.events.push(directive.event);
      return { ok: true };
    },
  },
  action: {
    analyze: (d) => ({
      capabilities: ["invoke"],
      dependencies: d.id ? [d.id] : [],
    }),
    execute: (directive, frame, engine) => {
      const result = engine.invoke(directive.id, directive.params, frame);
      return { ok: result.success, data: result.data };
    },
  },
  halt: HALT_HANDLER,
};

// ── 2. Engine — runtime de execução ──

const engine = createActionEngine({ handlers });

// ── 3. Analyzer — análise estática (opt-in) ──

const analyzer = createActionAnalyzer({ engine });
engine.on("register", (e) => analyzer.processRegistration(e));
engine.on("unregister", (e) => analyzer.processUnregistration(e));

// ── 4. Rules — triggers condicionais ──

const rules = createRuleEngine({ actionEngine: engine });

// ── 5. Events — dispatch de listeners ──

const events = createEventProcessor({ actionEngine: engine });

// ── 6. Registrar e usar ──

engine.register([
  { id: "heal", directives: [{ type: "state", target: "hp", value: 100 }] },
]);

rules.register([{
  id: "auto-heal",
  priority: 100,
  when: (ctx) => ctx.hp < 50,
  then: [
    { type: "action", id: "heal" },
    { type: "emit", event: "healed" },
  ],
}]);

events.register([{
  id: "on-healed",
  priority: 100,
  on: "healed",
  then: [{ type: "state", target: "healCount", value: 1 }],
}]);

// Runtime
const ctx = { hp: 30, events: [], healCount: 0 };
rules.evaluate(ctx);                               // auto-heal fires → heal + emit
events.processEvents([{ event: "healed" }], ctx);  // on-healed fires

// Análise estática
analyzer.capabilitiesOf("rule:auto-heal");  // Set { "invoke", "write", "emit" }
analyzer.dependenciesOf("rule:auto-heal");  // Set { "heal" }
```

---

## Os 4 Componentes

### ActionEngine — Runtime

Motor de execução. Registra ações (ID + diretivas), valida em register-time, compila executores (interpret/JIT), invoca em O(1). Handlers dão semântica — o engine orquestra.

```typescript
const engine = createActionEngine({ handlers });

engine.register([{
  id: "checkout",
  directives: [
    { type: "state", target: "status", value: "paid" },
    { type: "emit", event: "payment-processed" },
  ],
}]);

engine.setContext(ctx);
const result = engine.invoke("checkout");
// result.success, result.appliedCount, result.errors
```

Lifecycle events (`register`, `unregister`) permitem que camadas externas (analyzer) observem sem acoplamento.

### ActionAnalyzer — Análise Estática

Observa o engine via read-only accessors e lifecycle events. Constrói grafo de dependências, infere capabilities transitivas, detecta ciclos, valida composition control.

```typescript
const analyzer = createActionAnalyzer({ engine });

// Wire lifecycle events
engine.on("register", (e) => analyzer.processRegistration(e));
engine.on("unregister", (e) => analyzer.processUnregistration(e));

// Queries
analyzer.capabilitiesOf("checkout");   // Set { "write", "emit" }
analyzer.dependenciesOf("checkout");   // Set { ... }
analyzer.inCycle("checkout");          // false
analyzer.getStats();                   // { totalActions, totalEdges, ... }
```

Opt-in: o engine funciona sem analyzer. Quando presente, valida contratos sem afetar runtime.

### RuleEngine — Triggers Condicionais

Loop de `when(ctx) → invoke()`. Rules são normalizadas em hidden actions (`rule:{id}`) no engine. O RuleEngine não executa diretivas — delega tudo pro engine.

```typescript
const rules = createRuleEngine({ actionEngine: engine });

rules.register([{
  id: "heal-when-low",
  priority: 100,
  when: (ctx) => ctx.hp < 50,
  then: [{ type: "state", target: "hp", value: 100 }],
}]);

const result = rules.evaluate(ctx);
// result.matched, result.skipped, result.counters
```

Sub-rules habilitam branching condicional. Hooks (`beforeRule`, `afterRule`) habilitam governança. Halt para a avaliação de forma controlada.

### EventProcessor — Dispatch de Listeners

Listeners escutam eventos por nome. Normalizados em hidden actions (`event:{id}`) no engine. Match por nome, execução por prioridade desc. Halt é scoped ao evento — não contamina o próximo da fila.

```typescript
const events = createEventProcessor({ actionEngine: engine });

events.defineEvents([{ event: "save", tags: ["domain:billing"] }]);

events.register([{
  id: "on-save",
  priority: 100,
  on: "save",
  then: [{ type: "state", target: "saved", value: true }],
}]);

const result = events.processEvents([{ event: "save" }], ctx);
// result.processedEvents, result.eventResults, result.unprocessedEvents
```

---

## Composição — Como Tudo se Conecta

### Hidden Actions

Rules e listeners são hidden actions no engine. O RuleEngine registra `rule:{id}`. O EventProcessor registra `event:{id}`. O engine não sabe a origem — trata todas como actions normais. Isso significa que o analyzer valida **tudo** no mesmo grafo:

```
engine.registeredIds:
  "checkout"              ← action direta
  "rule:auto-heal"        ← hidden action da rule
  "event:on-payment"      ← hidden action do listener
  "eventdef:payment"      ← nó de definição de evento

analyzer.graph:
  rule:auto-heal → checkout → eventdef:payment
                              ↑
  event:on-payment ──────────┘
```

### Wiring

O SDK não faz wiring automático. O consumer conecta os componentes:

```typescript
// Analyzer observa engine
engine.on("register", (e) => analyzer.processRegistration(e));
engine.on("unregister", (e) => analyzer.processUnregistration(e));

// Rules e Events recebem o engine
const rules = createRuleEngine({ actionEngine: engine });
const events = createEventProcessor({ actionEngine: engine });
```

Máxima flexibilidade: o consumer decide quando e como conectar. O engine não sabe quem escuta. O analyzer não sabe quem o alimenta.

### Fluxo Típico de Execução

```
1. rules.evaluate(ctx)
   │
   ├─ when(ctx) === true   → engine.invoke("rule:{id}")
   │                          ├─ handler "state" → muta ctx
   │                          ├─ handler "emit"  → registra evento
   │                          └─ handler "action" → engine.invoke(child)
   │
   └─ result.matched = ["rule-a", "rule-b"]

2. events.processEvents(queue, ctx)
   │
   ├─ match listeners by event name
   │  └─ engine.invoke("event:{id}")
   │     └─ handlers executam diretivas
   │
   └─ result.processedEvents = 2

3. analyzer.capabilitiesOf("rule:rule-a")
   └─ Set { "write", "emit", "invoke" }
```

Rules avaliam. Events processam. Engine executa. Analyzer observa. Cada um no seu papel.

### Batch — Registro Cruzado

Batch permite registrar actions, rules, events e eventdefs em uma única transação. O engine adia lifecycle events até `endBatch()`. Forward references resolvem:

```typescript
engine.beginBatch();
rules.register([...]);           // Usa action que ainda não existe
events.defineEvents([...]);      // Define eventdefs
engine.register([...]);          // Registra a action referenciada
events.register([...]);          // Registra listeners
engine.endBatch();               // Analyzer recebe tudo de uma vez
```

---

## Dois Modos de Import

### Root — factories e tipos essenciais

Para começar rápido. Exporta as 4 factories e os tipos mais usados, sem colisão de nomes entre packages.

```typescript
// Factories
import {
  createActionEngine,
  createActionAnalyzer,
  createRuleEngine,
  createEventProcessor,
} from "@statedelta-actions/sdk";

// Types
import type {
  HandlerDefinition,
  ActionDefinition,
  IActionEngine,
  IActionAnalyzer,
  RuleDefinition,
  EventListenerDefinition,
  Directive,
  ExecutionFrame,
} from "@statedelta-actions/sdk";
```

### Subpath — acesso completo por package

Para quem precisa de exports específicos (propagators, matching, JIT, etc). Cada subpath re-exporta **tudo** do package original.

```typescript
// Core — primitivas (ExecutionFrame, hooks, slots, intercept)
import { createRootFrame, composeHooks } from "@statedelta-actions/sdk/core";

// Graph — grafo de dependências (ciclos, topo sort, propagators)
import { DependencyGraph, DEFAULT_PROPAGATORS } from "@statedelta-actions/sdk/graph";

// Actions — ActionEngine (validação, compilação, invoke)
import { createActionEngine, RESERVED_TYPES } from "@statedelta-actions/sdk/actions";

// Analyzer — análise estática (graph queries, composition control, permissions)
import { createActionAnalyzer, compileManifest } from "@statedelta-actions/sdk/analyzer";

// Rules — RuleEngine (invocação condicional por triggers)
import { createRuleEngine, HALT_HANDLER } from "@statedelta-actions/sdk/rules";

// Events — EventProcessor (dispatch de listeners por evento)
import { createEventProcessor, createEmitAnalyzer } from "@statedelta-actions/sdk/events";
```

---

## Packages Incluídos

| Subpath | Package | Descrição |
|---------|---------|-----------|
| `/core` | `@statedelta-actions/core` | Primitivas: ExecutionFrame, hooks, slots, intercept |
| `/graph` | `@statedelta-actions/graph` | Grafo de dependências: ciclos, topo sort, propagators, dirty tracking |
| `/actions` | `@statedelta-actions/actions` | ActionEngine: validação, compilação JIT, invoke O(1) |
| `/analyzer` | `@statedelta-actions/analyzer` | ActionAnalyzer: análise estática, capabilities, composition control |
| `/rules` | `@statedelta-actions/rules` | RuleEngine: invocação condicional por triggers e sub-rules |
| `/events` | `@statedelta-actions/events` | EventProcessor: dispatch de listeners por nome de evento |

---

## Três Modos de Operação

O consumer escolhe o nível de análise. Cada modo é uma composição incremental:

### JS mode — Engine only

```typescript
const engine = createActionEngine({ handlers });
engine.register([...]);
engine.invoke("action");
```

Runtime puro. Zero overhead de análise. Funciona: registration, invoke, JIT, hooks, batch.

### TS mode — Engine + Analyzer

```typescript
const engine = createActionEngine({ handlers });
const analyzer = createActionAnalyzer({ engine });
// wire events...
```

Tudo do JS mode + grafo de dependências, capabilities transitivas, detecção de ciclos, declaration conflicts.

### TS strict — Engine + Analyzer + Composition Control

```typescript
const analyzer = createActionAnalyzer({
  engine,
  accessManifest: {
    rules: [{
      source: { tags: { include: ["write"] } },
      target: { tags: { include: ["readonly"] } },
      effect: "deny",
    }],
  },
  tierValidation: true,
});
```

Tudo do TS mode + composition control declarativo (quem pode depender de quem) + tier validation (hierarquia numérica de acesso).

---

## Por que usar o SDK

Packages individuais têm versões independentes. Se você instala `@statedelta-actions/actions@0.2.0` e `@statedelta-actions/analyzer@0.1.0`, pode haver incompatibilidade de tipos (ex: `IAnalyzableEngine` mudou entre versões).

O SDK garante que todos os packages estão na versão que foi **testada junta**. Uma única dependência, zero risco de mismatch.

```json
{
  "dependencies": {
    "@statedelta-actions/sdk": "^0.1.0"
  }
}
```

Em vez de:

```json
{
  "dependencies": {
    "@statedelta-actions/core": "^0.1.0",
    "@statedelta-actions/graph": "^0.1.0",
    "@statedelta-actions/actions": "^0.1.0",
    "@statedelta-actions/analyzer": "^0.1.0",
    "@statedelta-actions/rules": "^0.1.0",
    "@statedelta-actions/events": "^0.1.0"
  }
}
```

Além de versões sincronizadas, o SDK inclui uma suite de **91 testes de integração** que validam a composição cross-package — cenários que nenhum package individual consegue testar sozinho.

---

## Documentação dos Packages

Cada package tem documentação completa de API, arquitetura interna e decisões de design:

| Package | README | Architecture | Decisions |
|---------|--------|-------------|-----------|
| actions | [README](../actions/README.md) | [ARCHITECTURE](../actions/docs/ARCHITECTURE.md) | [DECISIONS](../actions/docs/DECISIONS.md) |
| analyzer | [README](../analyzer/README.md) | [ARCHITECTURE](../analyzer/docs/ARCHITECTURE.md) | [DECISIONS](../analyzer/docs/DECISIONS.md) |
| rules | [README](../rules/README.md) | [ARCHITECTURE](../rules/docs/ARCHITECTURE.md) | [DECISIONS](../rules/docs/DECISIONS.md) |
| events | [README](../events/README.md) | [ARCHITECTURE](../events/docs/ARCHITECTURE.md) | [DECISIONS](../events/docs/DECISIONS.md) |
| graph | — | [ARCHITECTURE](../graph/docs/ARCHITECTURE.md) | [DECISIONS](../graph/docs/DECISIONS.md) |
| core | — | — | — |

Para a test architecture do SDK (helpers, test map, decisões), ver [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md).

---

## Licença

MIT