service-bridge 1.6.0-dev.33 → 1.7.0-dev.50

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
@@ -73,7 +73,7 @@ Node.js SDK for [ServiceBridge](https://servicebridge.dev) — production-ready
73
73
 
74
74
  **Saga / distributed transactions** — DAG workflows with typed steps (`rpc`, `event`, `event_wait`, `sleep`, child workflow). Compensations and rollbacks via workflow step dependencies.
75
75
 
76
- **AI agent orchestration** — Stream LLM tokens via realtime run streams with replay. Orchestrate multi-step AI pipelines as workflows.
76
+ **AI agent orchestration** — Stream LLM tokens via realtime trace streams with replay. Orchestrate multi-step AI pipelines as workflows.
77
77
 
78
78
  **Full-stack observability** — Every RPC call, event delivery, workflow step, and HTTP request traced automatically. One timeline, one dashboard. Prometheus metrics and Loki-compatible log API included.
79
79
 
@@ -116,7 +116,7 @@ const sb = servicebridge(
116
116
  process.env.SERVICEBRIDGE_SERVICE_KEY!,
117
117
  );
118
118
 
119
- const result = await sb.rpc<{ ok: boolean; txId: string }>("payments/charge", {
119
+ const result = await sb.rpc<{ ok: boolean; txId: string }>("payment.charge", {
120
120
  orderId: "ord_42",
121
121
  amount: 4990,
122
122
  });
@@ -171,7 +171,7 @@ await payments.serve({ host: "localhost" });
171
171
  const orders = servicebridge("localhost:14445", process.env.SERVICEBRIDGE_SERVICE_KEY!);
172
172
 
173
173
  // Call payments, then publish event
174
- const charge = await orders.rpc<{ ok: boolean; txId: string }>("payments/charge", {
174
+ const charge = await orders.rpc<{ ok: boolean; txId: string }>("payment.charge", {
175
175
  orderId: "ord_42",
176
176
  amount: 4990,
177
177
  });
@@ -203,8 +203,8 @@ await notifications.serve({ host: "localhost" });
203
203
  // --- Orchestrate as a workflow ---
204
204
 
205
205
  await orders.workflow("order.fulfillment", [
206
- { id: "reserve", type: "rpc", ref: "inventory/reserve" },
207
- { id: "charge", type: "rpc", ref: "payments/charge", deps: ["reserve"] },
206
+ { id: "reserve", type: "rpc", ref: "inventory.reserve" },
207
+ { id: "charge", type: "rpc", ref: "payment.charge", deps: ["reserve"] },
208
208
  { id: "wait_dlv", type: "event_wait", ref: "shipping.delivered", deps: ["charge"] },
209
209
  { id: "notify", type: "event", ref: "orders.fulfilled", deps: ["wait_dlv"] },
210
210
  ]);
@@ -236,7 +236,7 @@ Every step above — RPC, event publish, event delivery, workflow execution —
236
236
  - **Metrics** — Prometheus-compatible `/metrics` endpoint (30+ metric families)
237
237
  - **Logs** — structured log ingest with Loki-compatible query API
238
238
  - **Alerts** — runtime alerts for delivery failures, errors, and service health
239
- - **Dashboard** — realtime web UI for runs, events, workflows, jobs, DLQ, service map, and service keys
239
+ - **Dashboard** — realtime web UI for traces, events, workflows, jobs, DLQ, service map, and service keys
240
240
 
241
241
  ---
242
242
 
@@ -262,7 +262,7 @@ Every step above — RPC, event publish, event delivery, workflow execution —
262
262
  ### Cross-SDK parity notes
263
263
 
264
264
  ServiceBridge keeps the core API shape consistent across Node.js, Go, and Python:
265
- constructor, RPC, events, jobs, workflows, `runWorkflow`, streams, serve/stop, and `ServiceBridgeError`.
265
+ constructor, RPC, events, jobs, workflows, `executeWorkflow`, streams, serve/stop, and `ServiceBridgeError`.
266
266
 
267
267
  Constructor-level defaults for `timeout`, `retries`, and `retryDelay` are available
268
268
  across all three SDKs. Parity differences are naming-only (language idioms):
@@ -324,7 +324,9 @@ type WorkerTLSOpts = {
324
324
  rpc<T = unknown>(fn: string, payload?: unknown, opts?: RpcOpts): Promise<T>
325
325
  ```
326
326
 
327
- Calls a registered RPC handler on another service. Direct gRPC path, no proxy.
327
+ Calls a registered RPC handler on another worker. Direct gRPC path, no proxy.
328
+
329
+ **Function name** — `fn` is a single **global function name** (the same string passed to `handleRpc` on the callee), e.g. `payment.charge` or `user.get`. It must be unique in the catalog and **must not contain `/`**.
328
330
 
329
331
  `RpcOpts`:
330
332
 
@@ -338,7 +340,9 @@ Calls a registered RPC handler on another service. Direct gRPC path, no proxy.
338
340
  | `mode` | `"direct" \| "proxy"` | Transport mode. `"direct"` (default) connects directly to the worker. `"proxy"` routes through the control plane when direct connection is unavailable. |
339
341
 
340
342
  ```ts
341
- const user = await sb.rpc<{ id: string; name: string }>("users/get", { id: "u_1" }, {
343
+ const user = await sb.rpc<{ id: string; name: string }>("user.get", { id: "u_1" });
344
+
345
+ const user2 = await sb.rpc<{ id: string; name: string }>("user.get", { id: "u_1" }, {
342
346
  timeout: 5000,
343
347
  retries: 2,
344
348
  });
@@ -398,7 +402,7 @@ Registers a scheduled or delayed job.
398
402
  | `retryPolicyJson` | `string` | Retry policy JSON string. |
399
403
 
400
404
  ```ts
401
- await sb.job("billing/collect", {
405
+ await sb.job("billing.collect", {
402
406
  cron: "0 * * * *",
403
407
  timezone: "UTC",
404
408
  via: "rpc",
@@ -443,8 +447,8 @@ interface WorkflowOpts {
443
447
 
444
448
  ```ts
445
449
  await sb.workflow("order.fulfillment", [
446
- { id: "reserve", type: "rpc", ref: "inventory/reserve" },
447
- { id: "charge", type: "rpc", ref: "payments/charge", deps: ["reserve"] },
450
+ { id: "reserve", type: "rpc", ref: "inventory.reserve" },
451
+ { id: "charge", type: "rpc", ref: "payment.charge", deps: ["reserve"] },
448
452
  { id: "wait_5m", type: "sleep", durationMs: 300_000, deps: ["charge"] },
449
453
  { id: "notify", type: "event", ref: "orders.fulfilled", deps: ["wait_5m"] },
450
454
  ]);
@@ -458,44 +462,44 @@ await sb.workflow("checkout.flow", steps, { stepTimeoutMs: 60_000 });
458
462
 
459
463
  ---
460
464
 
461
- ### `runWorkflow(name, input?, opts?)`
465
+ ### `executeWorkflow(name, input?, opts?)`
462
466
 
463
467
  ```ts
464
- runWorkflow(name: string, input?: unknown, opts?: RunWorkflowOpts): Promise<{ runId: string; traceId: string }>
468
+ executeWorkflow(name: string, input?: unknown, opts?: ExecuteWorkflowOpts): Promise<{ traceId: string; groupTraceId: string }>
465
469
  ```
466
470
 
467
- Starts a workflow run on demand. The workflow must be registered first via `workflow()`.
468
- An alternative to scheduling via `job(target, { via: "workflow" })` — triggers the run immediately.
471
+ Starts a workflow execution on demand. The workflow must be registered first via `workflow()`.
472
+ An alternative to scheduling via `job(target, { via: "workflow" })` — triggers the execution immediately.
469
473
 
470
474
  | Parameter | Type | Default | Description |
471
475
  |---|---|---|---|
472
476
  | `name` | `string` | required | Name of a previously registered workflow. |
473
477
  | `input` | `unknown` | `undefined` | Optional JSON-serializable input payload. |
474
478
 
475
- Returns `{ runId, traceId }`. Use `traceId` with `watchRun()` to observe execution in real time.
479
+ Returns `{ traceId, groupTraceId }`. Use `traceId` with `watchTrace()` to observe execution in real time.
476
480
 
477
- `RunWorkflowOpts`:
481
+ `ExecuteWorkflowOpts`:
478
482
 
479
483
  | Option | Type | Description |
480
484
  |---|---|---|
481
- | `traceId` | `string` | Override trace ID for this workflow run. |
485
+ | `traceId` | `string` | Override trace ID for this workflow execution. |
482
486
 
483
487
  ```ts
484
- const { runId, traceId } = await sb.runWorkflow("user.onboarding", { userId: "u_123" });
488
+ const { traceId, groupTraceId } = await sb.executeWorkflow("user.onboarding", { userId: "u_123" });
485
489
  ```
486
490
 
487
491
  ---
488
492
 
489
- ### `cancelWorkflowRun(runId)`
493
+ ### `cancelWorkflow(traceId)`
490
494
 
491
495
  ```ts
492
- cancelWorkflowRun(runId: string): Promise<void>
496
+ cancelWorkflow(traceId: string): Promise<void>
493
497
  ```
494
498
 
495
499
  Cancels a running workflow instance.
496
500
 
497
501
  ```ts
498
- await sb.cancelWorkflowRun("run_01HQ...XYZ");
502
+ await sb.cancelWorkflow("trace_01HQ...XYZ");
499
503
  ```
500
504
 
501
505
  ---
@@ -531,7 +535,7 @@ Registers an RPC handler. Chainable.
531
535
  | `allowedCallers` | `string[]` | Allow-list of caller service names. |
532
536
 
533
537
  ```ts
534
- sb.handleRpc("ai/generate", async (payload: { prompt: string }, ctx) => {
538
+ sb.handleRpc("ai.generate", async (payload: { prompt: string }, ctx) => {
535
539
  await ctx?.stream.write({ token: "Hello" }, "output");
536
540
  await ctx?.stream.write({ token: " world" }, "output");
537
541
  return { text: "Hello world" };
@@ -542,7 +546,7 @@ sb.handleRpc("ai/generate", async (payload: { prompt: string }, ctx) => {
542
546
 
543
547
  | Method | Signature | Description |
544
548
  |---|---|---|
545
- | `write` | `write(data: unknown, key?: string): Promise<void>` | Append a real-time chunk to the run stream. |
549
+ | `write` | `write(data: unknown, key?: string): Promise<void>` | Append a real-time chunk to the trace stream. |
546
550
  | `end` | `end(key?: string): Promise<void>` | No-op placeholder for API symmetry (lifecycle managed by runtime). |
547
551
 
548
552
  ---
@@ -584,7 +588,7 @@ a consumer, the delivery moves to DLQ with reason `delivery_ttl_exceeded`.
584
588
  - `ctx.retry(delayMs?)` — ask for redelivery with optional delay
585
589
  - `ctx.reject(reason)` — move to DLQ immediately, bypassing remaining retries
586
590
  - `ctx.refs` — metadata (`topic`, `groupName`, `messageId`, `attempt`, `headers`)
587
- - `ctx.stream.write(...)` — append real-time chunks to run stream
591
+ - `ctx.stream.write(...)` — append real-time chunks to trace stream
588
592
 
589
593
  ```ts
590
594
  sb.handleEvent("orders.*", async (payload, ctx) => {
@@ -702,32 +706,32 @@ await sb.registerHttpEndpoint({
702
706
 
703
707
  ---
704
708
 
705
- ### `watchRun(runId, opts?)`
709
+ ### `watchTrace(traceId, opts?)`
706
710
 
707
711
  ```ts
708
- watchRun(runId: string, opts?: WatchRunOpts): AsyncIterable<RunStreamEvent>
712
+ watchTrace(traceId: string, opts?: WatchTraceOpts): AsyncIterable<TraceStreamEvent>
709
713
  ```
710
714
 
711
- Subscribes to a run stream with replay and live updates. `runId` is the stream
712
- identifier used by `ctx.stream.write(...)` (typically a trace ID).
715
+ Subscribes to a trace stream with replay and live updates. `traceId` is the stream
716
+ identifier used by `ctx.stream.write(...)`.
713
717
 
714
- `WatchRunOpts`:
718
+ `WatchTraceOpts`:
715
719
 
716
720
  | Option | Type | Default | Description |
717
721
  |---|---|---|---|
718
722
  | `key` | `string` | `""` | Stream key filter (`""` = all keys). |
719
723
  | `fromSequence` | `number` | `0` | Replay from sequence cursor. |
720
724
 
721
- `RunStreamEvent`:
725
+ `TraceStreamEvent`:
722
726
 
723
727
  | Field | Type | Description |
724
728
  |---|---|---|
725
- | `type` | `"chunk" \| "run_complete"` | Event kind. |
726
- | `runId` | `string` | Stream/run identifier being watched. |
729
+ | `type` | `"chunk" \| "trace_complete"` | Event kind. |
730
+ | `traceId` | `string` | Trace identifier being watched. |
727
731
  | `key` | `string` | Stream lane key. |
728
732
  | `sequence` | `number` | Monotonic sequence number. |
729
733
  | `data` | `unknown` | JSON-decoded chunk payload. |
730
- | `runStatus` | `string \| undefined` | Final status on `run_complete`. |
734
+ | `traceStatus` | `string \| undefined` | Final status on `trace_complete`. |
731
735
 
732
736
  Behavior:
733
737
 
@@ -737,11 +741,11 @@ Behavior:
737
741
  - Enforces internal queue limit `256`; overflow is fatal (consumer must drain promptly).
738
742
 
739
743
  ```ts
740
- for await (const evt of sb.watchRun(runId, { key: "output", fromSequence: 0 })) {
744
+ for await (const evt of sb.watchTrace(traceId, { key: "output", fromSequence: 0 })) {
741
745
  if (evt.type === "chunk") {
742
746
  process.stdout.write(String((evt.data as { token?: string }).token ?? ""));
743
747
  }
744
- if (evt.type === "run_complete") break;
748
+ if (evt.type === "trace_complete") break;
745
749
  }
746
750
  ```
747
751
 
@@ -766,18 +770,18 @@ if (tc) {
766
770
  }
767
771
  ```
768
772
 
769
- #### `runWithTraceContext(ctx, fn)`
773
+ #### `withTraceContext(ctx, fn)`
770
774
 
771
775
  ```ts
772
- runWithTraceContext<T>(ctx: { traceId: string; spanId: string }, fn: () => T): T
776
+ withTraceContext<T>(ctx: { traceId: string; spanId: string }, fn: () => T): T
773
777
  ```
774
778
 
775
779
  Runs a function inside an explicit trace context.
776
780
 
777
781
  ```ts
778
- import { runWithTraceContext } from "service-bridge";
782
+ import { withTraceContext } from "service-bridge";
779
783
 
780
- runWithTraceContext({ traceId: "trace-1", spanId: "span-1" }, async () => {
784
+ withTraceContext({ traceId: "trace-1", spanId: "span-1" }, async () => {
781
785
  await sb.event("audit.log", { action: "user.login" });
782
786
  });
783
787
  ```
@@ -807,7 +811,7 @@ app.use(servicebridgeMiddleware({
807
811
  }));
808
812
 
809
813
  app.get("/users/:id", async (req, res) => {
810
- const user = await req.servicebridge.rpc("users/get", { id: req.params.id });
814
+ const user = await req.servicebridge.rpc("user.get", { id: req.params.id });
811
815
  res.json(user);
812
816
  });
813
817
  ```
@@ -863,7 +867,7 @@ await app.register(servicebridgePlugin, {
863
867
  });
864
868
 
865
869
  app.get("/users/:id", wrapHandler(async (request, reply) => {
866
- const user = await request.servicebridge.rpc("users/get", {
870
+ const user = await request.servicebridge.rpc("user.get", {
867
871
  id: (request.params as any).id,
868
872
  });
869
873
  return reply.send(user);
@@ -960,7 +964,7 @@ const sb = servicebridge(
960
964
  import { servicebridge, ServiceBridgeError } from "service-bridge";
961
965
 
962
966
  try {
963
- await sb.rpc("payments/charge", { orderId: "ord_1" });
967
+ await sb.rpc("payment.charge", { orderId: "ord_1" });
964
968
  } catch (e) {
965
969
  if (e instanceof ServiceBridgeError) {
966
970
  console.error(e.component, e.operation, e.severity, e.retryable, e.code);
@@ -1148,12 +1152,12 @@ session.onConfigPush({
1148
1152
  'payment-svc': { mode: 'proxy', fallbackPolicy: 'fallback_to_direct' },
1149
1153
  },
1150
1154
  functionOverrides: {
1151
- 'payment-svc/charge': { mode: 'proxy', timeoutMs: 5000 },
1155
+ 'payment.charge': { mode: 'proxy', timeoutMs: 5000 },
1152
1156
  },
1153
1157
  });
1154
1158
 
1155
1159
  // Разрешить транспорт для функции
1156
- const mode = session.resolveTransportMode('payment-svc/charge'); // 'proxy'
1160
+ const mode = session.resolveTransportMode('payment.charge'); // 'proxy'
1157
1161
  ```
1158
1162
 
1159
1163
  ### Все события сессии
package/dist/express.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // http/src/express.ts
2
- import { runWithTraceContext } from "service-bridge";
2
+ import { withTraceContext } from "service-bridge";
3
3
 
4
4
  // http/src/trace.ts
5
5
  function parseTraceparent(traceparent) {
@@ -86,7 +86,7 @@ function servicebridgeMiddleware(options) {
86
86
  };
87
87
  res.on("finish", onFinish);
88
88
  res.on("close", onFinish);
89
- runWithTraceContext({ traceId: span.traceId, spanId: span.spanId }, () => {
89
+ withTraceContext({ traceId: span.traceId, spanId: span.spanId }, () => {
90
90
  next();
91
91
  });
92
92
  };
package/dist/fastify.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // http/src/fastify.ts
2
- import { runWithTraceContext } from "service-bridge";
2
+ import { withTraceContext } from "service-bridge";
3
3
 
4
4
  // http/src/trace.ts
5
5
  function parseTraceparent(traceparent) {
@@ -111,7 +111,7 @@ function wrapHandler(handler) {
111
111
  const traceId = request.traceId;
112
112
  const spanId = request.spanId;
113
113
  if (traceId && spanId) {
114
- return runWithTraceContext({ traceId, spanId }, () => handler(request, reply));
114
+ return withTraceContext({ traceId, spanId }, () => handler(request, reply));
115
115
  }
116
116
  return handler(request, reply);
117
117
  };