hobots 1.7.5 → 1.8.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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # hobots
2
2
 
3
- SDK JavaScript/TypeScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações.
3
+ SDK JavaScript/TypeScript da **Hobots** para instrumentar agentes (RPAs) e integrações.
4
4
 
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**).
5
+ - **Telemetria** — o que o programa **emite** sozinho: erros com stack trace (módulo **Issues** do app), performance (transactions/etapas) e heartbeats de uptime (módulo **Agentes**).
6
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
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.
@@ -30,7 +30,7 @@ O SDK expõe **duas capabilities** autenticadas pelo **mesmo Client Secret do ag
30
30
 
31
31
  | Capability | Como habilita | Para quê | Ciclo de vida |
32
32
  | --- | --- | --- | --- |
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. |
33
+ | **Telemetria** | sempre ativa no `init()` | O que o programa emite sozinho: erros, transactions/etapas, heartbeat. | Timers `unref`'d — **não** segura o processo. Chame `close()` no fim. |
34
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**:
@@ -158,16 +158,16 @@ Hobots.withScope((scope) => {
158
158
  });
159
159
  ```
160
160
 
161
- ### Performance: transactions e spans
161
+ ### Performance: transactions e etapas
162
162
 
163
163
  ```js
164
164
  const tx = Hobots.startTransaction('processar-lote', 'rpa.job');
165
165
 
166
- const span = tx.startChild('http.client', 'GET /api/notas');
166
+ const step = tx.startChild('http.client', 'GET /api/notas');
167
167
  await api.buscarNotas();
168
- span.setData('notas', 42).finish();
168
+ step.setData('notas', 42).finish();
169
169
 
170
- const filho = span.startChild('db.query', 'INSERT INTO notas'); // spans aninham
170
+ const filho = step.startChild('db.query', 'INSERT INTO notas'); // etapas aninham
171
171
  await gravar();
172
172
  filho.finish();
173
173
 
@@ -175,31 +175,11 @@ tx.setStatus('ok'); // ou 'error'
175
175
  tx.finish(); // só aqui a transaction é enviada (respeitando tracesSampleRate)
176
176
  ```
177
177
 
178
- - `startChild(op?, description?)` existe em `Transaction` **e** `Span` (aninhamento arbitrário).
179
- - Métodos encadeáveis: `setStatus`, `setData` (span), `setTag`/`setName` (transaction).
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()`.
178
+ - `startChild(op?, description?)` existe em `Transaction` **e** `Step` (aninhamento arbitrário).
179
+ - Métodos encadeáveis: `setStatus`, `setData` (step), `setTag`/`setName` (transaction).
180
+ - `finish()` na transaction fecha as etapas abertas e envia o payload; nada é enviado se ela não foi amostrada. A amostragem é decidida no `startTransaction()`.
181
181
 
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
-
184
- ### Crons (check-ins)
185
-
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
-
188
- ```js
189
- await Hobots.withMonitor(
190
- 'sync-notas',
191
- () => executarSync(),
192
- { schedule: '0 */2 * * *', timezone: 'America/Fortaleza' }
193
- );
194
- ```
195
-
196
- O `schedule` (expressão cron) faz o servidor **criar/atualizar o monitor automaticamente** (upsert) e habilita a detecção de **execução perdida**. Para controle manual:
197
-
198
- ```js
199
- const id = Hobots.checkIn({ monitorSlug: 'sync-notas', status: 'in_progress' });
200
- // … trabalho …
201
- Hobots.checkIn({ monitorSlug: 'sync-notas', status: 'ok', checkInId: id, durationMs: 1234 });
202
- ```
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) · [Step](./docs/concepts.md#step).
203
183
 
204
184
  ### Heartbeat (uptime)
205
185
 
@@ -353,7 +333,7 @@ Para parar de aceitar execuções **sem** derrubar a telemetria, use `stop(timeo
353
333
 
354
334
  | Import | Conteúdo |
355
335
  | --- | --- |
356
- | `hobots` | Tudo: `init`, telemetria (captura, transactions, crons, heartbeat), tasks (`register`/`start`/`stop`), `close`, classes e tipos. |
336
+ | `hobots` | Tudo: `init`, telemetria (captura, transactions, heartbeat), tasks (`register`/`start`/`stop`), `close`, classes e tipos. |
357
337
  | `hobots/protocol` | Tipos do wire format (telemetria e tasks). |
358
338
 
359
339
  Empacotado em **ESM e CommonJS** com **definições de tipos** (`.d.ts`) para todas as entradas.
@@ -364,11 +344,11 @@ Empacotado em **ESM e CommonJS** com **definições de tipos** (`.d.ts`) para to
364
344
 
365
345
  Guias detalhados acompanham o pacote em [`docs/`](./docs/README.md).
366
346
 
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.
347
+ Novo no vocabulário de observabilidade (transaction, step, breadcrumb, tag, context, extra, flush, close)? Comece por [Conceitos](./docs/concepts.md) — as outras páginas assumem esses termos.
368
348
 
369
349
  - [Conceitos](./docs/concepts.md) — o que cada coisa é, por que existe e quando escolher uma em vez da outra.
370
350
  - [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.
351
+ - [Telemetria](./docs/telemetry.md) — erros, breadcrumbs, escopo, transactions/etapas, heartbeat.
372
352
  - [Tasks](./docs/tasks.md) — handlers, `RunContext`, cancelamento, concorrência, idempotência.
373
353
  - [Referência de API](./docs/api-reference.md) — todas as funções e tabelas de opções com defaults.
374
354
  - [Protocolo & transporte](./docs/protocol.md) — o Client Secret, endpoints, envelope, retries.
package/dist/index.cjs CHANGED
@@ -33,12 +33,11 @@ __export(src_exports, {
33
33
  Client: () => Client,
34
34
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
35
35
  Scope: () => Scope,
36
- Span: () => Span,
36
+ Step: () => Step,
37
37
  Transaction: () => Transaction,
38
38
  addBreadcrumb: () => addBreadcrumb,
39
39
  captureException: () => captureException,
40
40
  captureMessage: () => captureMessage,
41
- checkIn: () => checkIn,
42
41
  close: () => close,
43
42
  flush: () => flush,
44
43
  getClient: () => getClient,
@@ -53,7 +52,6 @@ __export(src_exports, {
53
52
  start: () => start,
54
53
  startTransaction: () => startTransaction,
55
54
  stop: () => stop,
56
- withMonitor: () => withMonitor,
57
55
  withScope: () => withScope
58
56
  });
59
57
  module.exports = __toCommonJS(src_exports);
@@ -163,7 +161,7 @@ function scrubSecrets(text) {
163
161
 
164
162
  // src/utils.ts
165
163
  var SDK_NAME = "hobots";
166
- var SDK_VERSION = true ? "1.7.5" : "0.0.0-dev";
164
+ var SDK_VERSION = true ? "1.8.0" : "0.0.0-dev";
167
165
  function isNode() {
168
166
  return typeof process !== "undefined" && typeof process.versions?.node === "string";
169
167
  }
@@ -517,16 +515,6 @@ var Client = class {
517
515
  }
518
516
  });
519
517
  }
520
- sendCheckIn(payload) {
521
- this.transport.enqueue({
522
- type: "check_in",
523
- payload: {
524
- ...payload,
525
- release: payload.release ?? this.options.release,
526
- environment: payload.environment ?? this.options.environment ?? "production"
527
- }
528
- });
529
- }
530
518
  sendHeartbeat(payload) {
531
519
  this.transport.enqueue({
532
520
  type: "heartbeat",
@@ -719,10 +707,10 @@ var Scope = class _Scope {
719
707
  };
720
708
 
721
709
  // src/transaction.ts
722
- function spanId() {
710
+ function stepId() {
723
711
  return uuid4().slice(0, 16);
724
712
  }
725
- function spanLabel(op, description) {
713
+ function stepLabel(op, description) {
726
714
  return [op, description].filter(Boolean).join(" \u2014 ") || "(sem nome)";
727
715
  }
728
716
  function levelForStatus(status) {
@@ -749,14 +737,14 @@ function colorForStatus(status) {
749
737
  return "green";
750
738
  }
751
739
  }
752
- var Span = class {
753
- constructor(transaction, parentSpanId, op, description) {
740
+ var Step = class {
741
+ constructor(transaction, parentStepId, op, description) {
754
742
  this.transaction = transaction;
755
- this.parentSpanId = parentSpanId;
743
+ this.parentStepId = parentStepId;
756
744
  this.op = op;
757
745
  this.description = description;
758
746
  }
759
- spanId = spanId();
747
+ stepId = stepId();
760
748
  startTimestamp = nowISO();
761
749
  status = "ok";
762
750
  endTimestamp;
@@ -769,17 +757,17 @@ var Span = class {
769
757
  this.data = { ...this.data, [key]: value };
770
758
  return this;
771
759
  }
772
- /** Span aninhado (filho deste span). */
760
+ /** Step aninhada (filha desta step). */
773
761
  startChild(op, description) {
774
- return this.transaction.createSpan(this.spanId, op, description);
762
+ return this.transaction.createStep(this.stepId, op, description);
775
763
  }
776
764
  finish() {
777
765
  if (this.endTimestamp) return;
778
766
  this.endTimestamp = nowISO();
779
767
  this.transaction.emit(
780
- "span",
768
+ "step",
781
769
  "finish",
782
- spanLabel(this.op, this.description),
770
+ stepLabel(this.op, this.description),
783
771
  this.startTimestamp,
784
772
  this.endTimestamp,
785
773
  this.status
@@ -787,8 +775,8 @@ var Span = class {
787
775
  }
788
776
  toJSON() {
789
777
  return {
790
- span_id: this.spanId,
791
- parent_span_id: this.parentSpanId,
778
+ step_id: this.stepId,
779
+ parent_step_id: this.parentStepId,
792
780
  op: this.op,
793
781
  description: this.description,
794
782
  status: this.status,
@@ -808,10 +796,10 @@ var Transaction = class {
808
796
  this.emit("transaction", "start", op ? `${name} (${op})` : name);
809
797
  }
810
798
  eventId = uuid4();
811
- spanId = spanId();
799
+ stepId = stepId();
812
800
  startTimestamp = nowISO();
813
801
  status = "ok";
814
- spans = [];
802
+ steps = [];
815
803
  tags = {};
816
804
  finished = false;
817
805
  lifecycleSink;
@@ -819,7 +807,7 @@ var Transaction = class {
819
807
  // antes do RunReporter conectar) — replay no setLifecycleSink
820
808
  lifecycleBacklog = [];
821
809
  /**
822
- * Ecoa no terminal o início/fim de um span ou transaction (sempre, independente de
810
+ * Ecoa no terminal o início/fim de uma step ou transaction (sempre, independente de
823
811
  * sampling ou do debug) e espelha a linha no sink de lifecycle, se conectado — é
824
812
  * assim que os eventos de performance também aparecem nos logs da run no app.
825
813
  */
@@ -840,15 +828,15 @@ var Transaction = class {
840
828
  this.lifecycleBacklog = [];
841
829
  for (const [level, message] of backlog) sink(level, message);
842
830
  }
843
- createSpan(parentSpanId, op, description) {
844
- const span = new Span(this, parentSpanId, op, description);
845
- this.spans.push(span);
846
- this.emit("span", "start", spanLabel(op, description));
847
- return span;
831
+ createStep(parentStepId, op, description) {
832
+ const step = new Step(this, parentStepId, op, description);
833
+ this.steps.push(step);
834
+ this.emit("step", "start", stepLabel(op, description));
835
+ return step;
848
836
  }
849
- /** Span direto da transaction. */
837
+ /** Step direta da transaction. */
850
838
  startChild(op, description) {
851
- return this.createSpan(this.spanId, op, description);
839
+ return this.createStep(this.stepId, op, description);
852
840
  }
853
841
  setTag(key, value) {
854
842
  this.tags[key] = value;
@@ -865,7 +853,7 @@ var Transaction = class {
865
853
  finish() {
866
854
  if (this.finished) return;
867
855
  this.finished = true;
868
- for (const span of this.spans) span.finish();
856
+ for (const step of this.steps) step.finish();
869
857
  const endTimestamp = nowISO();
870
858
  this.emit(
871
859
  "transaction",
@@ -883,7 +871,7 @@ var Transaction = class {
883
871
  status: this.status,
884
872
  start_timestamp: this.startTimestamp,
885
873
  timestamp: endTimestamp,
886
- spans: this.spans.map((span) => span.toJSON()),
874
+ steps: this.steps.map((step) => step.toJSON()),
887
875
  tags: Object.keys(this.tags).length > 0 ? this.tags : void 0,
888
876
  run_id: this.runId
889
877
  };
@@ -891,34 +879,6 @@ var Transaction = class {
891
879
  }
892
880
  };
893
881
 
894
- // src/checkin.ts
895
- function sendCheckIn(client2, options) {
896
- const checkInId = options.checkInId ?? uuid4();
897
- client2.sendCheckIn({
898
- check_in_id: checkInId,
899
- monitor_slug: options.monitorSlug,
900
- status: options.status,
901
- duration_ms: options.durationMs,
902
- schedule: options.schedule,
903
- timezone: options.timezone
904
- });
905
- return checkInId;
906
- }
907
- async function withMonitorImpl(client2, captureError, monitorSlug, fn, options) {
908
- const base = { monitorSlug, schedule: options?.schedule, timezone: options?.timezone };
909
- const checkInId = sendCheckIn(client2, { ...base, status: "in_progress" });
910
- const startedAt = Date.now();
911
- try {
912
- const result = await fn();
913
- sendCheckIn(client2, { ...base, status: "ok", checkInId, durationMs: Date.now() - startedAt });
914
- return result;
915
- } catch (error) {
916
- sendCheckIn(client2, { ...base, status: "error", checkInId, durationMs: Date.now() - startedAt });
917
- captureError(error);
918
- throw error;
919
- }
920
- }
921
-
922
882
  // src/tasks/api.ts
923
883
  var POLL_TIMEOUT_MS = 3e4;
924
884
  var UPDATE_TIMEOUT_MS = 1e4;
@@ -1464,7 +1424,7 @@ var TaskAgent = class {
1464
1424
  {
1465
1425
  agent: {
1466
1426
  // identidade canônica do agente no painel — o mesmo instanceId do
1467
- // heartbeat do Monitor, então os dois canais convergem em um agente
1427
+ // heartbeat da Telemetria, então os dois canais convergem em um agente
1468
1428
  instance_id: this.instanceId,
1469
1429
  version: SDK_VERSION,
1470
1430
  host: hostname(),
@@ -1666,19 +1626,6 @@ function startTransaction(name, op) {
1666
1626
  const sampled = rate >= 1 || Math.random() < rate;
1667
1627
  return new Transaction(client, name, op, sampled);
1668
1628
  }
1669
- function checkIn(options) {
1670
- return client ? sendCheckIn(client, options) : void 0;
1671
- }
1672
- async function withMonitor(monitorSlug, fn, options) {
1673
- if (!client) return fn();
1674
- return withMonitorImpl(
1675
- client,
1676
- (error) => captureException(error, { tags: { monitor: monitorSlug } }),
1677
- monitorSlug,
1678
- fn,
1679
- options
1680
- );
1681
- }
1682
1629
  function flush(timeoutMs) {
1683
1630
  return client ? client.flush(timeoutMs) : Promise.resolve(true);
1684
1631
  }