hobots 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -42
- package/dist/index.cjs +105 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -124
- package/dist/index.d.ts +25 -124
- package/dist/index.js +105 -121
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +73 -4
- package/dist/protocol.d.ts +73 -4
- package/docs/README.md +8 -8
- package/docs/api-reference.md +40 -42
- package/docs/concepts.md +30 -15
- package/docs/getting-started.md +16 -16
- package/docs/monitor.md +8 -8
- package/docs/protocol.md +20 -22
- package/docs/{manager.md → tasks.md} +18 -18
- package/package.json +2 -7
- package/dist/manager/protocol.cjs +0 -19
- package/dist/manager/protocol.cjs.map +0 -1
- package/dist/manager/protocol.d.cts +0 -72
- package/dist/manager/protocol.d.ts +0 -72
- package/dist/manager/protocol.js +0 -1
- package/dist/manager/protocol.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
SDK JavaScript/TypeScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações.
|
|
4
4
|
|
|
5
|
-
- **
|
|
6
|
-
- **
|
|
5
|
+
- **Telemetria** — o que o programa **emite** sozinho: erros com stack trace (módulo **Issues** do app), performance (transactions/spans) e heartbeats de uptime (módulo **Agentes**), check-ins de cron (módulo **Monitores**).
|
|
6
|
+
- **Tasks** — execução **sob demanda**: o agente faz polling no app da Hobots, executa handlers registrados e reporta status e logs (módulo **Solicitações**).
|
|
7
7
|
|
|
8
|
-
**Um único import e um único `init()`** cobrem as duas capabilities. Cliente HTTP puro, **sem dependências de runtime**. Requer **Node 18+** (usa o `fetch` global);
|
|
8
|
+
**Um único import e um único `init()`** cobrem as duas capabilities. Cliente HTTP puro, **sem dependências de runtime**. Requer **Node 18+** (usa o `fetch` global); a telemetria também roda no browser para captura de erros.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -17,7 +17,7 @@ npm install hobots
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
|
-
import * as Hobots from 'hobots'; // um import só —
|
|
20
|
+
import * as Hobots from 'hobots'; // um import só — telemetria e tasks
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Também funciona em CommonJS: `const Hobots = require('hobots')`.
|
|
@@ -30,21 +30,21 @@ O SDK expõe **duas capabilities** autenticadas pelo **mesmo Client Secret do pr
|
|
|
30
30
|
|
|
31
31
|
| Capability | Como habilita | Para quê | Ciclo de vida |
|
|
32
32
|
| --- | --- | --- | --- |
|
|
33
|
-
| **
|
|
34
|
-
| **
|
|
33
|
+
| **Telemetria** | sempre ativa no `init()` | O que o programa emite sozinho: erros, transactions/spans, crons, heartbeat. | Timers `unref`'d — **não** segura o processo. Chame `close()` no fim. |
|
|
34
|
+
| **Tasks** | `tasks: true` (ou opções) no `init()` | Execução remota sob demanda via polling. | `start()` **segura o processo vivo** até `stop()`/`close()`. |
|
|
35
35
|
|
|
36
36
|
Você usa **uma, outra ou as duas**:
|
|
37
37
|
|
|
38
38
|
- Só saber se o robô quebrou, quanto demora e se está vivo? → `init({ clientSecret, heartbeat: true })`.
|
|
39
|
-
- Disparar o robô sob demanda a partir de um formulário no app? → `init({ clientSecret,
|
|
40
|
-
- Ambos? Passe `heartbeat` e `
|
|
39
|
+
- Disparar o robô sob demanda a partir de um formulário no app? → `init({ clientSecret, tasks: true })` + `register()` + `start()`.
|
|
40
|
+
- Ambos? Passe `heartbeat` e `tasks` no mesmo `init()` — o `instanceId` é a identidade única, e os dois canais convergem em **um agente** no painel. Com `tasks: true`, o heartbeat é **opcional**: o próprio poll de tasks já marca a presença do agente.
|
|
41
41
|
|
|
42
42
|
```js
|
|
43
43
|
Hobots.init({
|
|
44
44
|
clientSecret: 'hb_<64 hex>',
|
|
45
45
|
instanceId: 'vm-cliente-01',
|
|
46
|
-
heartbeat: true, //
|
|
47
|
-
|
|
46
|
+
heartbeat: true, // telemetria: "estou vivo" a cada 30s
|
|
47
|
+
tasks: { pollIntervalMs: 5_000 }, // execução sob demanda
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
@@ -52,14 +52,14 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
52
52
|
ctx.log.info('12 notas processadas'); // o retorno do handler é ignorado — reporte por log
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
Hobots.start(); // inicia o polling
|
|
55
|
+
Hobots.start(); // inicia o polling de tasks (segura o processo vivo)
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
60
60
|
## O Client Secret
|
|
61
61
|
|
|
62
|
-
Cada projeto tem **um único Client Secret** — a mesma credencial autentica
|
|
62
|
+
Cada projeto tem **um único Client Secret** — a mesma credencial autentica a telemetria **e** as tasks:
|
|
63
63
|
|
|
64
64
|
```
|
|
65
65
|
hb_<64 hex>
|
|
@@ -69,7 +69,7 @@ A credencial é **secreta** e viaja sempre no header `Authorization: Bearer` —
|
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
72
|
-
##
|
|
72
|
+
## Telemetria
|
|
73
73
|
|
|
74
74
|
Todas as funções abaixo são **no-op seguras** se `Hobots.init()` não foi chamado (com aviso no console).
|
|
75
75
|
|
|
@@ -93,14 +93,14 @@ Hobots.init({
|
|
|
93
93
|
| `clientSecret` | `string` | **obrigatório** | o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
|
|
94
94
|
| `environment` | `string` | `'production'` | ambiente lógico |
|
|
95
95
|
| `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
|
|
96
|
-
| `instanceId` | `string` | **obrigatório** | identidade única da instância — heartbeat
|
|
96
|
+
| `instanceId` | `string` | **obrigatório** | identidade única da instância — heartbeat e poll de tasks convergem nela |
|
|
97
97
|
| `tags` | `Record<string,string>` | — | tags aplicadas a todos os eventos |
|
|
98
98
|
| `sampleRate` | `number` | `1` | amostragem de erros (0..1) |
|
|
99
99
|
| `tracesSampleRate` | `number` | `1` | amostragem de transactions (0..1) |
|
|
100
100
|
| `maxBreadcrumbs` | `number` | `100` | tamanho do buffer de breadcrumbs |
|
|
101
101
|
| `captureUnhandled` | `boolean` | `true` | handlers globais de erro (`uncaughtException`/`unhandledRejection`) |
|
|
102
102
|
| `heartbeat` | `boolean \| HeartbeatOptions` | `false` | heartbeat periódico (`true` usa defaults) |
|
|
103
|
-
| `
|
|
103
|
+
| `tasks` | `boolean \| TasksOptions` | `false` | habilita a execução sob demanda (`true` usa defaults) — veja [Tasks](#tasks-execução-sob-demanda) |
|
|
104
104
|
| `beforeSend` | `(event) => event \| null` | — | edita/descarta evento (retorne `null` para descartar) |
|
|
105
105
|
| `debug` | `boolean` | `false` | loga atividade do SDK |
|
|
106
106
|
| `flushIntervalMs` | `number` | `2000` | intervalo do flush automático do transport |
|
|
@@ -123,7 +123,7 @@ try {
|
|
|
123
123
|
Hobots.captureMessage('Lote processado com sucesso', 'success');
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
Ambas retornam o `event_id` (ou `undefined` se não inicializado). O hint aceita `level`, `tags`, `extra` e `fingerprint`. Erros **não tratados** são capturados e flushados automaticamente antes do processo sair — desligue com `captureUnhandled: false`.
|
|
126
|
+
Ambas retornam o `event_id` (ou `undefined` se não inicializado). O hint aceita `level`, `tags`, `extra` e `fingerprint`. Erros **não tratados** são capturados e flushados automaticamente antes do processo sair — desligue com `captureUnhandled: false`. Os eventos aparecem agrupados em issues no módulo **Issues** do app.
|
|
127
127
|
|
|
128
128
|
`Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success'`. Use `'success'` para reportar itens concluídos com êxito — contam como eventos, mas **não** viram issue nem disparam alertas.
|
|
129
129
|
|
|
@@ -179,11 +179,11 @@ tx.finish(); // só aqui a transaction é enviada (respeitando tracesSam
|
|
|
179
179
|
- Métodos encadeáveis: `setStatus`, `setData` (span), `setTag`/`setName` (transaction).
|
|
180
180
|
- `finish()` na transaction fecha os spans abertos e envia o payload; nada é enviado se ela não foi amostrada. A amostragem é decidida no `startTransaction()`.
|
|
181
181
|
|
|
182
|
-
Dentro de um handler
|
|
182
|
+
Dentro de um handler de task, `startTransaction()` **retorna a transaction da própria run** (`ctx.tx`) em vez de criar uma segunda — cada execução tem exatamente **uma** transaction. Conceitos: [Transaction](./docs/concepts.md#transaction) · [Span](./docs/concepts.md#span).
|
|
183
183
|
|
|
184
184
|
### Crons (check-ins)
|
|
185
185
|
|
|
186
|
-
Monitora jobs agendados: check-in `in_progress` na entrada, `ok`/`error` na saída, com duração medida. O jeito recomendado é `withMonitor`, que faz o par e captura exceções:
|
|
186
|
+
Monitora jobs agendados no módulo **Monitores** do app: check-in `in_progress` na entrada, `ok`/`error` na saída, com duração medida. O jeito recomendado é `withMonitor`, que faz o par e captura exceções:
|
|
187
187
|
|
|
188
188
|
```js
|
|
189
189
|
await Hobots.withMonitor(
|
|
@@ -212,7 +212,9 @@ Hobots.init({
|
|
|
212
212
|
});
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()`; os campos são `intervalMs`, `name` (default: o `instanceId`) e `metadata` — valores em [Tempos e intervalos](./docs/api-reference.md#tempos-e-intervalos). O primeiro batimento sai **na hora** em que o `init()` roda, não depois do primeiro intervalo.
|
|
215
|
+
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()`; os campos são `intervalMs`, `name` (default: o `instanceId`) e `metadata` — valores em [Tempos e intervalos](./docs/api-reference.md#tempos-e-intervalos). O primeiro batimento sai **na hora** em que o `init()` roda, não depois do primeiro intervalo.
|
|
216
|
+
|
|
217
|
+
O heartbeat é **essencial** para agentes só de telemetria; com `tasks: true` ele é **opcional**, porque o poll de tasks já marca a presença do agente no painel. Conceito: [Heartbeat](./docs/concepts.md#heartbeat).
|
|
216
218
|
|
|
217
219
|
### Flush e close
|
|
218
220
|
|
|
@@ -221,13 +223,13 @@ await Hobots.flush(2000); // envia o buffer, mantém o SDK vivo
|
|
|
221
223
|
await Hobots.close(2000); // flush final + para o heartbeat + fecha o transport
|
|
222
224
|
```
|
|
223
225
|
|
|
224
|
-
Chame `close` antes do processo sair. Os timers
|
|
226
|
+
Chame `close` antes do processo sair. Os timers da telemetria são `unref`'d — ela **não** segura o processo vivo sozinha.
|
|
225
227
|
|
|
226
228
|
---
|
|
227
229
|
|
|
228
|
-
##
|
|
230
|
+
## Tasks (execução sob demanda)
|
|
229
231
|
|
|
230
|
-
Capability de **execução remota sob demanda**, habilitada com `
|
|
232
|
+
Capability de **execução remota sob demanda**, habilitada com `tasks: true` (ou opções) no `init()`. O agente faz polling no app, executa os handlers registrados quando aparece trabalho e reporta status e logs incrementais — cada execução aparece no módulo **Solicitações** do app. Mesmo Client Secret, mesmo `debug` e o `instanceId` como identidade — nenhum handler global extra é instalado.
|
|
231
233
|
|
|
232
234
|
### Ciclo de vida
|
|
233
235
|
|
|
@@ -235,7 +237,7 @@ Capability de **execução remota sob demanda**, habilitada com `manager: true`
|
|
|
235
237
|
Hobots.init({
|
|
236
238
|
clientSecret: 'hb_<64 hex>',
|
|
237
239
|
instanceId: 'vm-cliente-01',
|
|
238
|
-
|
|
240
|
+
tasks: true, // ou { pollIntervalMs, concurrency, ... }
|
|
239
241
|
});
|
|
240
242
|
|
|
241
243
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
@@ -251,13 +253,13 @@ process.on('SIGINT', () => {
|
|
|
251
253
|
});
|
|
252
254
|
```
|
|
253
255
|
|
|
254
|
-
- `init({
|
|
255
|
-
- `register(task, handler)` — `task` é o `task_slug` configurado no formulário do app. Registre **antes** de `start()`. Funciona até antes do `init()`; com
|
|
256
|
-
- `start()` — começa o polling. Lança se o `init()` não configurou `
|
|
257
|
-
- `stop(timeoutMs?)` — para **só o
|
|
256
|
+
- `init({ tasks })` — cria o agente. Chamar `init()` de novo para o agente anterior e o substitui (o registry de handlers é preservado).
|
|
257
|
+
- `register(task, handler)` — `task` é o `task_slug` configurado no formulário do app (**Configurações → Formulários**). Registre **antes** de `start()`. Funciona até antes do `init()`; com as tasks desabilitadas, avisa no console.
|
|
258
|
+
- `start()` — começa o polling. Lança se o `init()` não configurou `tasks` ou se nenhuma task foi registrada.
|
|
259
|
+
- `stop(timeoutMs?)` — para **só o polling de tasks**: encerra o polling e aguarda as runs ativas (default 30s); a telemetria continua. Retorna `false` se estourou o timeout.
|
|
258
260
|
- `close(timeoutMs?)` — encerra **tudo**: agente (aguardando runs em voo) → heartbeat → flush final do transport.
|
|
259
261
|
|
|
260
|
-
| Opção (`
|
|
262
|
+
| Opção (`TasksOptions`) | Tipo | Default | Descrição |
|
|
261
263
|
| --- | --- | --- | --- |
|
|
262
264
|
| `pollIntervalMs` | `number` | `5000` | intervalo entre polls sem trabalho (mínimo `1000`) |
|
|
263
265
|
| `concurrency` | `number` | `1` | runs simultâneas (clamp 1..5) |
|
|
@@ -266,18 +268,18 @@ process.on('SIGINT', () => {
|
|
|
266
268
|
| `cancelCheckIntervalMs` | `number` | `5000` | heartbeat de cancelamento por run (clamp 1000..15000) — também é o sinal de vida da run |
|
|
267
269
|
| `installExitHandlers` | `boolean` | `true` | handlers de SIGINT/SIGTERM/uncaughtException que reportam as runs ativas como `AgentTerminated` antes do processo morrer; nunca interferem quando o programa tem handler próprio |
|
|
268
270
|
|
|
269
|
-
O Client Secret, o `debug` e a identidade do agente (`instanceId`) vêm do `init()` — o heartbeat
|
|
271
|
+
O Client Secret, o `debug` e a identidade do agente (`instanceId`) vêm do `init()` — o heartbeat e o poll de tasks convergem em **um agente** no painel automaticamente.
|
|
270
272
|
|
|
271
273
|
### O handler e o `RunContext`
|
|
272
274
|
|
|
273
275
|
```ts
|
|
274
|
-
type
|
|
276
|
+
type TaskHandler<P = Record<string, unknown>> =
|
|
275
277
|
(params: P, ctx: RunContext) => void | Promise<void>;
|
|
276
278
|
|
|
277
279
|
interface RunContext {
|
|
278
280
|
runId: string;
|
|
279
281
|
task: string;
|
|
280
|
-
log
|
|
282
|
+
log: RunLogger; // ctx.log.debug/info/warn/error/success(message)
|
|
281
283
|
tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
|
|
282
284
|
signal: AbortSignal;
|
|
283
285
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
@@ -286,15 +288,15 @@ interface RunContext {
|
|
|
286
288
|
```
|
|
287
289
|
|
|
288
290
|
- **`params`** — os dados do formulário configurado no app (JSON validado). Tipável: `Hobots.register<{ lote: number }>(...)`.
|
|
289
|
-
- **`ctx.log.<level>(message)`** — logs enviados **incrementalmente** ao app (PATCHes com throttle), visíveis na
|
|
290
|
-
- **`ctx.tx`** — a transaction de performance desta run, já correlacionada e finalizada pelo SDK. Use `ctx.tx.startChild(op, description)` para medir as etapas — elas viram o waterfall da execução no app. Conceito: [ctx.tx](./docs/concepts.md#transaction-de-run-ctxtx).
|
|
291
|
+
- **`ctx.log.<level>(message)`** — níveis `debug`, `info`, `warn`, `error` e `success`; logs enviados **incrementalmente** ao app (PATCHes com throttle), visíveis na solicitação quase em tempo real; também impressos no terminal local, coloridos por nível.
|
|
292
|
+
- **`ctx.tx`** — a transaction de performance desta run, já correlacionada e finalizada pelo SDK. Use `ctx.tx.startChild(op, description)` para medir as etapas — elas viram o waterfall da execução no app. `startTransaction()` chamado dentro do handler retorna essa mesma transaction. Conceito: [ctx.tx](./docs/concepts.md#transaction-de-run-ctxtx).
|
|
291
293
|
- **`ctx.signal`** — `AbortSignal` que dispara quando a run é **cancelada no app**, em **timeout** ou no **shutdown**.
|
|
292
294
|
- **`ctx.throwIfCanceled()`** — o ponto de parada de uma linha; lança `RunCanceled` se o `signal` já disparou.
|
|
293
295
|
- **`ctx.sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim).
|
|
294
296
|
- **Retorno** — **ignorado**: o SDK não captura nem envia o valor retornado pelo handler (resultados podem conter dados sensíveis e não são coletados).
|
|
295
297
|
- **Erro lançado** — a run é reportada como `failed` (mensagem cap 10k, stack 20k).
|
|
296
298
|
|
|
297
|
-
> **Dados sensíveis:** `ctx.log
|
|
299
|
+
> **Dados sensíveis:** `ctx.log` e mensagens/stack de erros **são enviados ao servidor** e ficam visíveis no app. Não inclua senhas, tokens, dados pessoais ou qualquer informação sensível em logs e mensagens de erro.
|
|
298
300
|
|
|
299
301
|
### Cancelamento cooperativo
|
|
300
302
|
|
|
@@ -331,13 +333,13 @@ Ainda assim, escreva handlers **idempotentes**: a janela de re-entrega pós-clai
|
|
|
331
333
|
|
|
332
334
|
## Encerramento gracioso
|
|
333
335
|
|
|
334
|
-
`close(timeoutMs?)` encerra tudo na ordem certa: para o
|
|
336
|
+
`close(timeoutMs?)` encerra tudo na ordem certa: para o polling de tasks (aguardando a run atual), para o heartbeat e faz o flush final do transport.
|
|
335
337
|
|
|
336
338
|
```js
|
|
337
|
-
// só
|
|
339
|
+
// só telemetria: não segura o processo, mas faça o flush final para não perder eventos
|
|
338
340
|
await Hobots.close(2_000);
|
|
339
341
|
|
|
340
|
-
// com
|
|
342
|
+
// com tasks: segura o processo por design — aguarde a run atual
|
|
341
343
|
process.on('SIGINT', () => {
|
|
342
344
|
void Hobots.close(15_000).then(() => process.exit(0));
|
|
343
345
|
});
|
|
@@ -351,8 +353,8 @@ Para parar de aceitar execuções **sem** derrubar a telemetria, use `stop(timeo
|
|
|
351
353
|
|
|
352
354
|
| Import | Conteúdo |
|
|
353
355
|
| --- | --- |
|
|
354
|
-
| `hobots` | Tudo: `init`,
|
|
355
|
-
| `hobots/protocol` | Tipos do wire format (
|
|
356
|
+
| `hobots` | Tudo: `init`, telemetria (captura, transactions, crons, heartbeat), tasks (`register`/`start`/`stop`), `close`, classes e tipos. |
|
|
357
|
+
| `hobots/protocol` | Tipos do wire format (telemetria e tasks). |
|
|
356
358
|
|
|
357
359
|
Empacotado em **ESM e CommonJS** com **definições de tipos** (`.d.ts`) para todas as entradas.
|
|
358
360
|
|
|
@@ -365,9 +367,9 @@ Guias detalhados acompanham o pacote em [`docs/`](./docs/README.md).
|
|
|
365
367
|
Novo no vocabulário de observabilidade (transaction, span, breadcrumb, tag, context, extra, flush, close)? Comece por [Conceitos](./docs/concepts.md) — as outras páginas assumem esses termos.
|
|
366
368
|
|
|
367
369
|
- [Conceitos](./docs/concepts.md) — o que cada coisa é, por que existe e quando escolher uma em vez da outra.
|
|
368
|
-
- [Getting started](./docs/getting-started.md) — instalação, Client Secret, primeiro `init`,
|
|
369
|
-
- [
|
|
370
|
-
- [
|
|
370
|
+
- [Getting started](./docs/getting-started.md) — instalação, Client Secret, primeiro `init`, telemetria e tasks.
|
|
371
|
+
- [Telemetria](./docs/monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons, heartbeat.
|
|
372
|
+
- [Tasks](./docs/tasks.md) — handlers, `RunContext`, cancelamento, concorrência, idempotência.
|
|
371
373
|
- [Referência de API](./docs/api-reference.md) — todas as funções e tabelas de opções com defaults.
|
|
372
374
|
- [Protocolo & transporte](./docs/protocol.md) — o Client Secret, endpoints, envelope, retries.
|
|
373
375
|
|