@forwardimpact/librpc 0.1.110 → 0.1.112

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
@@ -13,11 +13,24 @@ transport.
13
13
  import { Server, Client, createClient, createTracer } from '@forwardimpact/librpc';
14
14
  ```
15
15
 
16
+ ## Unary deadlines
17
+
18
+ Every unary call carries one absolute gRPC deadline. The deadline spans
19
+ all retry attempts. The default is 60s. That default matches the slowest
20
+ unary in practice (embedding model inference). A hung connection fails
21
+ with `DEADLINE_EXCEEDED`. Retryable errors (UNAVAILABLE and friends)
22
+ cycle only until the call spends its budget. The first attempt past the
23
+ deadline fails immediately. `DEADLINE_EXCEEDED` gets no retry. Override
24
+ the deadline per service with the `deadline` config key (milliseconds)
25
+ in the service's config block. Once the key exists there, the
26
+ `SERVICE_{NAME}_DEADLINE` env var overrides it. Streaming calls are
27
+ exempt. Keepalive bounds them, and long-lived streams are legitimate.
28
+
16
29
  ## Documentation
17
30
 
18
31
  - [Ship a Service Endpoint](https://www.forwardimpact.team/docs/libraries/typed-contracts/ship-endpoint/index.md)
19
32
  — ship and consume a gRPC service with typed contracts, authentication,
20
- retries, and health checks; `fit-unary` is the command-line client for it.
33
+ retries, and health checks. `fit-unary` is the command-line client for it.
21
34
  - [Keep Types Synced with Proto Definitions](https://www.forwardimpact.team/docs/libraries/typed-contracts/index.md)
22
- — the full workflow for defining proto contracts and generating typed base
35
+ — the full workflow to define proto contracts and generate typed base
23
36
  classes and clients.
package/bin/fit-unary.js CHANGED
@@ -23,13 +23,13 @@ const definition = {
23
23
  title: "Ship a Service Endpoint",
24
24
  url: "https://www.forwardimpact.team/docs/libraries/typed-contracts/ship-endpoint/index.md",
25
25
  description:
26
- "Ship and consume a gRPC service with typed contracts, authentication, retries, and health checks; fit-unary is the command-line client for it.",
26
+ "Ship and consume a gRPC service with typed contracts, authentication, retries, and health checks. fit-unary is the command-line client for it.",
27
27
  },
28
28
  {
29
29
  title: "Keep Types Synced with Proto Definitions",
30
30
  url: "https://www.forwardimpact.team/docs/libraries/typed-contracts/index.md",
31
31
  description:
32
- "The full workflow for defining proto contracts and generating typed base classes and clients.",
32
+ "The full workflow to define proto contracts and generate typed base classes and clients.",
33
33
  },
34
34
  ],
35
35
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forwardimpact/librpc",
3
- "version": "0.1.110",
3
+ "version": "0.1.112",
4
4
  "description": "gRPC server and client framework — ship service endpoints without reimplementing transport.",
5
5
  "keywords": [
6
6
  "grpc",
package/src/auth.js CHANGED
@@ -12,7 +12,7 @@ export class HmacAuth {
12
12
 
13
13
  /**
14
14
  * Creates a new HMAC authenticator instance
15
- * @param {string} secret - Shared secret key for HMAC generation (minimum 32 characters)
15
+ * @param {string} secret - Shared secret key to generate the HMAC (minimum 32 characters)
16
16
  * @param {number} tokenLifetimeSeconds - Token lifetime in seconds (default: 60)
17
17
  * @param {object} [options] - Optional collaborators
18
18
  * @param {() => number} [options.now] - Injectable clock (default: Date.now)
@@ -36,7 +36,7 @@ export class HmacAuth {
36
36
 
37
37
  /**
38
38
  * Generates an HMAC token for the specified service
39
- * @param {string} serviceId - Identifier of the service requesting authentication
39
+ * @param {string} serviceId - Identifier of the service that requests authentication
40
40
  * @returns {string} Base64 encoded HMAC token
41
41
  * @throws {Error} When serviceId is invalid
42
42
  */
@@ -59,7 +59,7 @@ export class HmacAuth {
59
59
  /**
60
60
  * Verifies an HMAC token and extracts service information
61
61
  * @param {string} token - Base64 encoded HMAC token to verify
62
- * @returns {object} Verification result containing serviceId and isValid
62
+ * @returns {object} Verification result with serviceId and isValid
63
63
  * @throws {Error} When token format is invalid
64
64
  */
65
65
  verifyToken(token) {
@@ -95,7 +95,7 @@ export class HmacAuth {
95
95
  };
96
96
  }
97
97
 
98
- // Check token expiration
98
+ // Check whether the token expired
99
99
  const now = this.#now();
100
100
  if (now - timestamp > this.#tokenLifetimeMs) {
101
101
  return {
@@ -152,7 +152,8 @@ export class HmacAuth {
152
152
 
153
153
  /**
154
154
  * gRPC interceptor for HMAC-based service authentication
155
- * Handles automatic token attachment for outgoing requests and validation for incoming requests
155
+ * Adds a token to each outgoing request automatically and validates each
156
+ * incoming request
156
157
  */
157
158
  export class Interceptor {
158
159
  #authenticator;
@@ -232,14 +233,14 @@ export class Interceptor {
232
233
  };
233
234
  }
234
235
 
235
- // Add service ID to call context for potential use by handlers
236
+ // Add the service ID to the call context so handlers can use it
236
237
  call.serviceId = verification.serviceId;
237
238
  };
238
239
  }
239
240
 
240
241
  /**
241
242
  * Validates an incoming gRPC call's authentication
242
- * This is a helper method for manual authentication validation
243
+ * This helper method validates the authentication manually
243
244
  * @param {object} call - gRPC call object
244
245
  * @returns {object} Verification result with isValid, serviceId, and error properties
245
246
  */
package/src/base.js CHANGED
@@ -6,7 +6,7 @@ import { Interceptor, HmacAuth } from "./auth.js";
6
6
  import { definitions } from "./generated/definitions/exports.js";
7
7
 
8
8
  /**
9
- * Capitalize first letter of a string
9
+ * Capitalize the first letter of a string
10
10
  * @param {string} str - String to capitalize
11
11
  * @returns {string} Capitalized string
12
12
  */
@@ -16,18 +16,18 @@ export function capitalizeFirstLetter(str) {
16
16
 
17
17
  /**
18
18
  * Default grpc factory that creates gRPC dependencies
19
- * @returns {object} Object containing grpc
19
+ * @returns {object} Object with grpc
20
20
  */
21
21
  export function createGrpc() {
22
22
  return { grpc };
23
23
  }
24
24
 
25
25
  /**
26
- * Default auth factory that creates an authentication interceptor. Reads
27
- * `SERVICE_SECRET` from the injected `runtime.proc.env` rather than
28
- * constructing its own process collaborator — the runtime is threaded from the
29
- * entry point through `Server`/`Client` (no leaf-collaborator construction in
30
- * src, Success Criterion 9).
26
+ * Default auth factory that creates an authentication interceptor. It reads
27
+ * `SERVICE_SECRET` from the injected `runtime.proc.env`. It does not construct
28
+ * its own process collaborator. The entry point threads the runtime through
29
+ * `Server`/`Client` (no leaf-collaborator construction in src, Success
30
+ * Criterion 9).
31
31
  * @param {string} serviceName - Name of the service for the interceptor
32
32
  * @param {import("@forwardimpact/libutil/runtime").Runtime} runtime - Injected runtime bag
33
33
  * @returns {Interceptor} Configured interceptor instance
@@ -91,8 +91,8 @@ export class Rpc {
91
91
  const { grpc } = grpcFn();
92
92
  this.#grpc = grpc;
93
93
 
94
- // Setup authentication (the default factory reads SERVICE_SECRET off the
95
- // injected runtime; a mock authFn ignores it)
94
+ // Set up authentication. The default factory reads SERVICE_SECRET off the
95
+ // injected runtime. A mock authFn ignores it.
96
96
  this.#auth = authFn(this.config.name, runtime);
97
97
 
98
98
  // Create observer with logger and tracer
@@ -124,7 +124,7 @@ export class Rpc {
124
124
  tracer = () => this.#observer.tracer();
125
125
 
126
126
  /**
127
- * Get pre-compiled service definition
127
+ * Get the pre-compiled service definition
128
128
  * @param {string} serviceName - Service name (e.g., "Agent", "Vector")
129
129
  * @returns {object} Pre-compiled service definition
130
130
  */
package/src/client.js CHANGED
@@ -9,12 +9,22 @@ import {
9
9
  capitalizeFirstLetter,
10
10
  } from "./base.js";
11
11
 
12
+ // No unary call waits forever. Every call carries one absolute gRPC
13
+ // deadline that spans all retry attempts. So a hung connection fails with
14
+ // DEADLINE_EXCEEDED, and so does a retryable-error grind (exponential
15
+ // backoff on UNAVAILABLE). Neither one blocks the caller forever. The
16
+ // default fits the slowest unary in practice (embedding model inference).
17
+ // Override it per service with the `deadline` config key.
18
+ const DEFAULT_UNARY_DEADLINE_MS = 60_000;
19
+
12
20
  /**
13
- * Creates a gRPC client with consistent API using pre-compiled definitions
21
+ * Creates a gRPC client with a consistent API from pre-compiled definitions
14
22
  */
15
23
  export class Client extends Rpc {
16
24
  #client;
17
25
  #retry;
26
+ #clock;
27
+ #deadlineMs;
18
28
 
19
29
  /**
20
30
  * Creates a new Client instance
@@ -25,7 +35,7 @@ export class Client extends Rpc {
25
35
  * @param {(serviceName: string, logger: object, tracer: object) => object} observerFn - Observer factory
26
36
  * @param {() => {grpc: object}} grpcFn - gRPC factory
27
37
  * @param {(serviceName: string, runtime: object) => object} authFn - Auth factory
28
- * @param {import("@forwardimpact/libutil").Retry} [retry] - Optional retry instance for handling transient errors
38
+ * @param {import("@forwardimpact/libutil").Retry} [retry] - Optional retry instance that handles transient errors
29
39
  */
30
40
  constructor(
31
41
  config,
@@ -39,18 +49,20 @@ export class Client extends Rpc {
39
49
  ) {
40
50
  super(config, runtime, logger, tracer, observerFn, grpcFn, authFn);
41
51
  this.#retry = retry || createRetry({ retries: 10, delay: 1000 });
52
+ this.#clock = runtime.clock;
53
+ this.#deadlineMs = Number(config.deadline) || DEFAULT_UNARY_DEADLINE_MS;
42
54
  this.#setupClient();
43
55
  }
44
56
 
45
57
  /**
46
- * Sets up the gRPC client using pre-compiled definition
58
+ * Sets up the gRPC client from the pre-compiled definition
47
59
  * @private
48
60
  */
49
61
  #setupClient() {
50
62
  const serviceName = capitalizeFirstLetter(this.config.name);
51
63
  const serviceDefinition = this.getServiceDefinition(serviceName);
52
64
 
53
- // In case default host is used, resort to a well-known service name
65
+ // If the config uses the default host, resort to a well-known service name
54
66
  const host =
55
67
  this.config.host === "0.0.0.0"
56
68
  ? `${this.config.name}.guide.local`
@@ -61,7 +73,7 @@ export class Client extends Rpc {
61
73
  interceptors: [this.auth().createClientInterceptor()],
62
74
  };
63
75
 
64
- // Configure client with keepalive for long-running streams
76
+ // Configure the client with keepalive for long-running streams
65
77
  // https://github.com/grpc/grpc-node/blob/master/doc/keepalive.md
66
78
  const channelOptions = {
67
79
  "grpc.keepalive_time_ms": 30000, // Send keepalive ping every 30 seconds
@@ -72,7 +84,7 @@ export class Client extends Rpc {
72
84
  };
73
85
  const clientCredentials = this.grpc().credentials.createInsecure();
74
86
 
75
- // Create client using pre-compiled service definition
87
+ // Create the client from the pre-compiled service definition
76
88
  const ClientConstructor = this.grpc().makeGenericClientConstructor(
77
89
  serviceDefinition,
78
90
  serviceName,
@@ -81,6 +93,15 @@ export class Client extends Rpc {
81
93
  this.#client = new ClientConstructor(uri, clientCredentials, options);
82
94
  }
83
95
 
96
+ /**
97
+ * Close the underlying gRPC channel. This releases its sockets and timers
98
+ * so short-lived processes (CLIs, tests) can exit promptly.
99
+ * @returns {void}
100
+ */
101
+ close() {
102
+ this.#client.close();
103
+ }
104
+
84
105
  /**
85
106
  * Call a gRPC method with automatic CLIENT span tracing and observability.
86
107
  * Supports unary calls.
@@ -199,7 +220,12 @@ export class Client extends Rpc {
199
220
  }
200
221
 
201
222
  /**
202
- * Internal unary call handler with retry logic
223
+ * Internal unary call handler with retry logic. The handler computes the
224
+ * absolute deadline once and shares it with every retry attempt. So
225
+ * retryable errors repeat only until the call spends its budget. The
226
+ * first attempt past the deadline fails at once with DEADLINE_EXCEEDED,
227
+ * which is deliberately not retryable. Streaming calls are exempt.
228
+ * Keepalive bounds them, and long-lived streams are legitimate.
203
229
  * @param {string} methodName - The name of the method
204
230
  * @param {object} request - Request object
205
231
  * @param {object} metadata - gRPC Metadata instance
@@ -207,15 +233,21 @@ export class Client extends Rpc {
207
233
  * @private
208
234
  */
209
235
  async #performUnaryCall(methodName, request, metadata) {
236
+ const options = { deadline: this.#clock.now() + this.#deadlineMs };
210
237
  return await this.#retry.execute(() => {
211
238
  return new Promise((resolve, reject) => {
212
- this.#client[methodName](request, metadata, (error, response) => {
213
- if (error) {
214
- reject(error);
215
- } else {
216
- resolve(response);
217
- }
218
- });
239
+ this.#client[methodName](
240
+ request,
241
+ metadata,
242
+ options,
243
+ (error, response) => {
244
+ if (error) {
245
+ reject(error);
246
+ } else {
247
+ resolve(response);
248
+ }
249
+ },
250
+ );
219
251
  });
220
252
  });
221
253
  }
@@ -9,8 +9,8 @@ export { GhuserServiceDefinition } from "./ghuser.js";
9
9
  export { GraphServiceDefinition } from "./graph.js";
10
10
  export { MapServiceDefinition } from "./map.js";
11
11
  export { PathwayServiceDefinition } from "./pathway.js";
12
+ export { SpanServiceDefinition } from "./span.js";
12
13
  export { TenancyServiceDefinition } from "./tenancy.js";
13
- export { TraceServiceDefinition } from "./trace.js";
14
14
  export { VectorServiceDefinition } from "./vector.js";
15
15
 
16
16
  // Import service definitions to make them available for aggregation
@@ -21,8 +21,8 @@ import { GhuserServiceDefinition } from "./ghuser.js";
21
21
  import { GraphServiceDefinition } from "./graph.js";
22
22
  import { MapServiceDefinition } from "./map.js";
23
23
  import { PathwayServiceDefinition } from "./pathway.js";
24
+ import { SpanServiceDefinition } from "./span.js";
24
25
  import { TenancyServiceDefinition } from "./tenancy.js";
25
- import { TraceServiceDefinition } from "./trace.js";
26
26
  import { VectorServiceDefinition } from "./vector.js";
27
27
 
28
28
  // Aggregate exports for convenience
@@ -34,8 +34,8 @@ export const definitions = {
34
34
  graph: GraphServiceDefinition,
35
35
  map: MapServiceDefinition,
36
36
  pathway: PathwayServiceDefinition,
37
+ span: SpanServiceDefinition,
37
38
  tenancy: TenancyServiceDefinition,
38
- trace: TraceServiceDefinition,
39
39
  vector: VectorServiceDefinition,
40
40
  };
41
41
 
@@ -0,0 +1,50 @@
1
+ import { span } from "@forwardimpact/libtype";
2
+
3
+ /**
4
+ * Pre-compiled gRPC service definition for Span
5
+ * Generated at build time
6
+ */
7
+ export const SpanServiceDefinition = {
8
+ RecordSpan: {
9
+ path: '/span.Span/RecordSpan',
10
+ requestStream: false,
11
+ responseStream: false,
12
+ requestSerialize: (value) => {
13
+ return Buffer.from(span.SpanItem.encode(value).finish());
14
+ },
15
+ requestDeserialize: (value) => {
16
+ return span.SpanItem.toObject(
17
+ span.SpanItem.decode(value)
18
+ );
19
+ },
20
+ responseSerialize: (value) => {
21
+ return Buffer.from(span.RecordResponse.encode(value).finish());
22
+ },
23
+ responseDeserialize: (value) => {
24
+ return span.RecordResponse.toObject(
25
+ span.RecordResponse.decode(value)
26
+ );
27
+ },
28
+ },
29
+ QuerySpans: {
30
+ path: '/span.Span/QuerySpans',
31
+ requestStream: false,
32
+ responseStream: false,
33
+ requestSerialize: (value) => {
34
+ return Buffer.from(span.QueryRequest.encode(value).finish());
35
+ },
36
+ requestDeserialize: (value) => {
37
+ return span.QueryRequest.toObject(
38
+ span.QueryRequest.decode(value)
39
+ );
40
+ },
41
+ responseSerialize: (value) => {
42
+ return Buffer.from(span.QueryResponse.encode(value).finish());
43
+ },
44
+ responseDeserialize: (value) => {
45
+ return span.QueryResponse.toObject(
46
+ span.QueryResponse.decode(value)
47
+ );
48
+ },
49
+ },
50
+ };
@@ -9,8 +9,8 @@ export { GhuserBase } from "./ghuser/service.js";
9
9
  export { GraphBase } from "./graph/service.js";
10
10
  export { MapBase } from "./map/service.js";
11
11
  export { PathwayBase } from "./pathway/service.js";
12
+ export { SpanBase } from "./span/service.js";
12
13
  export { TenancyBase } from "./tenancy/service.js";
13
- export { TraceBase } from "./trace/service.js";
14
14
  export { VectorBase } from "./vector/service.js";
15
15
 
16
16
  // Client Classes
@@ -21,8 +21,8 @@ export { GhuserClient } from "./ghuser/client.js";
21
21
  export { GraphClient } from "./graph/client.js";
22
22
  export { MapClient } from "./map/client.js";
23
23
  export { PathwayClient } from "./pathway/client.js";
24
+ export { SpanClient } from "./span/client.js";
24
25
  export { TenancyClient } from "./tenancy/client.js";
25
- export { TraceClient } from "./trace/client.js";
26
26
  export { VectorClient } from "./vector/client.js";
27
27
 
28
28
  // Import service base classes to make them available for aggregation
@@ -33,8 +33,8 @@ import { GhuserBase } from "./ghuser/service.js";
33
33
  import { GraphBase } from "./graph/service.js";
34
34
  import { MapBase } from "./map/service.js";
35
35
  import { PathwayBase } from "./pathway/service.js";
36
+ import { SpanBase } from "./span/service.js";
36
37
  import { TenancyBase } from "./tenancy/service.js";
37
- import { TraceBase } from "./trace/service.js";
38
38
  import { VectorBase } from "./vector/service.js";
39
39
 
40
40
  // Import client classes to make them available for aggregation
@@ -45,8 +45,8 @@ import { GhuserClient } from "./ghuser/client.js";
45
45
  import { GraphClient } from "./graph/client.js";
46
46
  import { MapClient } from "./map/client.js";
47
47
  import { PathwayClient } from "./pathway/client.js";
48
+ import { SpanClient } from "./span/client.js";
48
49
  import { TenancyClient } from "./tenancy/client.js";
49
- import { TraceClient } from "./trace/client.js";
50
50
  import { VectorClient } from "./vector/client.js";
51
51
 
52
52
  // Aggregate exports for convenience
@@ -58,8 +58,8 @@ export const services = {
58
58
  GraphBase,
59
59
  MapBase,
60
60
  PathwayBase,
61
+ SpanBase,
61
62
  TenancyBase,
62
- TraceBase,
63
63
  VectorBase,
64
64
  };
65
65
 
@@ -71,8 +71,8 @@ export const clients = {
71
71
  GraphClient,
72
72
  MapClient,
73
73
  PathwayClient,
74
+ SpanClient,
74
75
  TenancyClient,
75
- TraceClient,
76
76
  VectorClient,
77
77
  };
78
78
 
@@ -87,8 +87,8 @@ export default {
87
87
  GraphBase,
88
88
  MapBase,
89
89
  PathwayBase,
90
+ SpanBase,
90
91
  TenancyBase,
91
- TraceBase,
92
92
  VectorBase,
93
93
  BridgeClient,
94
94
  EmbeddingClient,
@@ -97,7 +97,7 @@ export default {
97
97
  GraphClient,
98
98
  MapClient,
99
99
  PathwayClient,
100
+ SpanClient,
100
101
  TenancyClient,
101
- TraceClient,
102
102
  VectorClient,
103
103
  };
@@ -3,15 +3,15 @@
3
3
  import { Client } from "@forwardimpact/librpc/client.js";
4
4
  import { createAuth, createGrpc } from "@forwardimpact/librpc/base.js";
5
5
  import { createObserver } from "@forwardimpact/libtelemetry";
6
- import { trace } from "@forwardimpact/libtype";
6
+ import { span } from "@forwardimpact/libtype";
7
7
 
8
8
  /**
9
- * Typed client for the Trace gRPC service.
9
+ * Typed client for the Span gRPC service.
10
10
  * Extends the `Client` class for shared gRPC client functionality.
11
11
  */
12
- export class TraceClient extends Client {
12
+ export class SpanClient extends Client {
13
13
  /**
14
- * Creates a new Trace client instance
14
+ * Creates a new Span client instance
15
15
  * @param {object} config - Service configuration
16
16
  * @param {import("@forwardimpact/libutil/runtime").Runtime} runtime - Injected runtime bag (required; the default auth factory reads SERVICE_SECRET from it)
17
17
  * @param {import("@forwardimpact/libtelemetry").Logger} [logger] - Optional logger instance
@@ -24,35 +24,35 @@ export class TraceClient extends Client {
24
24
 
25
25
  /**
26
26
  * Call the `RecordSpan` RPC with request/response type conversion.
27
- * @param { trace.Span } req - Typed request message.
28
- * @returns { Promise<trace.RecordResponse> } Typed response message.
27
+ * @param { span.SpanItem } req - Typed request message.
28
+ * @returns { Promise<span.RecordResponse> } Typed response message.
29
29
  */
30
30
  async RecordSpan(req) {
31
31
  // Accept a typed message or a plain init object (coerced to the typed type).
32
32
  const message =
33
- req instanceof trace.Span
33
+ req instanceof span.SpanItem
34
34
  ? req
35
- : new trace.Span(req);
36
- const request = trace.Span.toObject(message);
35
+ : new span.SpanItem(req);
36
+ const request = span.SpanItem.toObject(message);
37
37
 
38
38
  // Make gRPC call (tracing handled by base Client class)
39
- return this.callUnary("RecordSpan", request, (res) => trace.RecordResponse.fromObject(res));
39
+ return this.callUnary("RecordSpan", request, (res) => span.RecordResponse.fromObject(res));
40
40
  }
41
41
 
42
42
  /**
43
43
  * Call the `QuerySpans` RPC with request/response type conversion.
44
- * @param { trace.QueryRequest } req - Typed request message.
45
- * @returns { Promise<trace.QueryResponse> } Typed response message.
44
+ * @param { span.QueryRequest } req - Typed request message.
45
+ * @returns { Promise<span.QueryResponse> } Typed response message.
46
46
  */
47
47
  async QuerySpans(req) {
48
48
  // Accept a typed message or a plain init object (coerced to the typed type).
49
49
  const message =
50
- req instanceof trace.QueryRequest
50
+ req instanceof span.QueryRequest
51
51
  ? req
52
- : new trace.QueryRequest(req);
53
- const request = trace.QueryRequest.toObject(message);
52
+ : new span.QueryRequest(req);
53
+ const request = span.QueryRequest.toObject(message);
54
54
 
55
55
  // Make gRPC call (tracing handled by base Client class)
56
- return this.callUnary("QuerySpans", request, (res) => trace.QueryResponse.fromObject(res));
56
+ return this.callUnary("QuerySpans", request, (res) => span.QueryResponse.fromObject(res));
57
57
  }
58
58
  }
@@ -1,15 +1,15 @@
1
1
  /* eslint no-unused-vars: "off" */
2
2
 
3
- import { trace } from "@forwardimpact/libtype";
3
+ import { span } from "@forwardimpact/libtype";
4
4
 
5
5
  /**
6
- * Base class for Trace service implementation
6
+ * Base class for Span service implementation
7
7
  */
8
- export class TraceBase {
8
+ export class SpanBase {
9
9
  config;
10
10
 
11
11
  /**
12
- * Creates a new Trace service instance
12
+ * Creates a new Span service instance
13
13
  * @param {object} config - Service configuration
14
14
  */
15
15
  constructor(config) {
@@ -19,8 +19,8 @@ export class TraceBase {
19
19
 
20
20
  /**
21
21
  * Must be implemented by subclass
22
- * @param { trace.Span } req - Request parameters
23
- * @returns { Promise<trace.RecordResponse> } Response object
22
+ * @param { span.SpanItem } req - Request parameters
23
+ * @returns { Promise<span.RecordResponse> } Response object
24
24
  */
25
25
  async RecordSpan(req) {
26
26
  throw new Error("RecordSpan not implemented");
@@ -28,8 +28,8 @@ export class TraceBase {
28
28
 
29
29
  /**
30
30
  * Must be implemented by subclass
31
- * @param { trace.QueryRequest } req - Request parameters
32
- * @returns { Promise<trace.QueryResponse> } Response object
31
+ * @param { span.QueryRequest } req - Request parameters
32
+ * @returns { Promise<span.QueryResponse> } Response object
33
33
  */
34
34
  async QuerySpans(req) {
35
35
  throw new Error("QuerySpans not implemented");
@@ -43,18 +43,18 @@ export class TraceBase {
43
43
  return {
44
44
  RecordSpan: async (call) => {
45
45
  // Validate and convert request
46
- const error = trace.Span.verify(call.request);
46
+ const error = span.SpanItem.verify(call.request);
47
47
  if (error) throw new Error(`RecordSpan: ${error}`);
48
- const req = trace.Span.fromObject(call.request);
48
+ const req = span.SpanItem.fromObject(call.request);
49
49
 
50
50
  // Call implementation
51
51
  return await this.RecordSpan(req);
52
52
  },
53
53
  QuerySpans: async (call) => {
54
54
  // Validate and convert request
55
- const error = trace.QueryRequest.verify(call.request);
55
+ const error = span.QueryRequest.verify(call.request);
56
56
  if (error) throw new Error(`QuerySpans: ${error}`);
57
- const req = trace.QueryRequest.fromObject(call.request);
57
+ const req = span.QueryRequest.fromObject(call.request);
58
58
 
59
59
  // Call implementation
60
60
  return await this.QuerySpans(req);