arvo-event-handler 1.1.7 → 1.1.9

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.
@@ -1,4 +1,5 @@
1
1
  import { ArvoContractRecord, ArvoEvent } from 'arvo-core';
2
+ import { ExecutionOpenTelemetryConfiguration } from './types';
2
3
  /**
3
4
  * Abstract base class for Arvo event handlers.
4
5
  *
@@ -14,22 +15,44 @@ export default abstract class AbstractArvoEventHandler {
14
15
  * Executes the event handling logic for a given Arvo event.
15
16
  *
16
17
  * @abstract
17
- * @param {ArvoEvent} event - The Arvo event to be processed.
18
+ * @param {ArvoEvent} event - The Arvo event to be processed. This event should conform
19
+ * to the expected schema for the specific handler implementation.
20
+ * @param {ExecutionOpenTelemetryConfiguration} opentelemetry - Configuration for OpenTelemetry
21
+ * integration, including tracing options
22
+ * and context inheritance settings.
18
23
  * @returns {Promise<ArvoEvent[]>} A promise that resolves to an array of resulting Arvo events.
24
+ * These events represent the outcome of processing the input event.
19
25
  *
20
26
  * @description
21
- * This method should contain the core logic for processing an Arvo event.
22
- * Implementations should handle the event according to their specific requirements
23
- * and return any resulting events.
27
+ * This method defines the core event processing logic that each concrete handler must implement.
28
+ * It should handle the complete lifecycle of an event, including:
29
+ * - Validation of the input event
30
+ * - Processing of the event according to business rules
31
+ * - Generation of any resulting events
32
+ * - Error handling and reporting
33
+ * - OpenTelemetry integration for observability
24
34
  *
25
- * @throws {Error} Implementations may throw errors for invalid inputs or processing failures.
35
+ * @throws {Error}
36
+ * - When the input event fails validation
37
+ * - When processing encounters an unrecoverable error
38
+ * - When the handler is unable to properly execute the event
26
39
  *
27
40
  * @remarks
28
- * - The method is asynchronous to allow for potentially time-consuming operations.
29
- * - The returned array may be empty if no new events are generated as a result of processing.
30
- * - Implementations should ensure proper error handling and event validation.
41
+ * Implementation considerations:
42
+ * - Ensure proper error handling and event validation
43
+ * - Implement appropriate retry logic for transient failures
44
+ * - Use the provided OpenTelemetry configuration for tracing
45
+ * - Consider performance implications for long-running operations
46
+ * - Maintain idempotency where appropriate
47
+ * - Document any specific requirements for event schemas
48
+ *
49
+ * The method should handle observability concerns by:
50
+ * - Creating appropriate spans for tracing
51
+ * - Recording relevant attributes and events
52
+ * - Properly handling span lifecycle (creation and completion)
53
+ * - Propagating context appropriately
31
54
  */
32
- abstract execute(event: ArvoEvent): Promise<ArvoEvent[]>;
55
+ abstract execute(event: ArvoEvent, opentelemetry: ExecutionOpenTelemetryConfiguration): Promise<ArvoEvent[]>;
33
56
  /**
34
57
  * Provides the schema for system error events.
35
58
  *
@@ -0,0 +1,33 @@
1
+ import { Tracer } from '@opentelemetry/api';
2
+ /**
3
+ * Configuration options for OpenTelemetry integration in execution context.
4
+ *
5
+ * This type defines how tracing should be configured and inherited within
6
+ * the execution pipeline.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const config: ExecutionOpenTelemetryConfiguration = {
11
+ * inheritFrom: 'event',
12
+ * tracer: new OpenTelemetry.Tracer('service-name')
13
+ * };
14
+ * ```
15
+ */
16
+ export type ExecutionOpenTelemetryConfiguration = {
17
+ /**
18
+ * Specifies the context from which to inherit OpenTelemetry context.
19
+ *
20
+ * @property {('event' | 'execution')} inheritFrom
21
+ * - 'event': Inherits context from the event that triggered the execution
22
+ * - 'execution': Inherits context from the parent execution context
23
+ */
24
+ inheritFrom: 'event' | 'execution';
25
+ /**
26
+ * Optional OpenTelemetry tracer instance to use for creating spans.
27
+ * If not provided, a default tracer may be used depending on the implementation.
28
+ *
29
+ * @property {Tracer} [tracer]
30
+ * @see {@link https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api.Tracer.html OpenTelemetry Tracer}
31
+ */
32
+ tracer?: Tracer;
33
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,6 +2,7 @@ import { ArvoContract, ArvoEvent, ArvoExecutionSpanKind, OpenInferenceSpanKind,
2
2
  import { IArvoEventHandler } from './types';
3
3
  import { SpanKind } from '@opentelemetry/api';
4
4
  import AbstractArvoEventHandler from '../AbstractArvoEventHandler';
5
+ import { ExecutionOpenTelemetryConfiguration } from '../AbstractArvoEventHandler/types';
5
6
  /**
6
7
  * Represents an event handler for Arvo contracts.
7
8
  *
@@ -45,6 +46,8 @@ export default class ArvoEventHandler<TContract extends ArvoContract> extends Ab
45
46
  * Executes the event handler for a given event.
46
47
  *
47
48
  * @param event - The event to handle.
49
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
50
+ * and context inheritance settings.
48
51
  * @returns A promise that resolves to an array of resulting ArvoEvents.
49
52
  *
50
53
  * @remarks
@@ -88,9 +91,7 @@ export default class ArvoEventHandler<TContract extends ArvoContract> extends Ab
88
91
  * - Propagates trace context to output events
89
92
  * - Handles error cases and sets appropriate span status
90
93
  */
91
- execute(event: ArvoEvent<ResolveArvoContractRecord<TContract['accepts']>, Record<string, any>, TContract['accepts']['type']>, opentelemetry?: {
92
- inheritFrom: 'event' | 'execution';
93
- }): Promise<ArvoEvent[]>;
94
+ execute(event: ArvoEvent<ResolveArvoContractRecord<TContract['accepts']>, Record<string, any>, TContract['accepts']['type']>, opentelemetry?: ExecutionOpenTelemetryConfiguration): Promise<ArvoEvent[]>;
94
95
  /**
95
96
  * Provides the schema for system error events.
96
97
  *
@@ -114,6 +114,8 @@ var ArvoEventHandler = /** @class */ (function (_super) {
114
114
  * Executes the event handler for a given event.
115
115
  *
116
116
  * @param event - The event to handle.
117
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
118
+ * and context inheritance settings.
117
119
  * @returns A promise that resolves to an array of resulting ArvoEvents.
118
120
  *
119
121
  * @remarks
@@ -162,11 +164,13 @@ var ArvoEventHandler = /** @class */ (function (_super) {
162
164
  var spanName, spanKinds, spanOptions, span, eventFactory;
163
165
  var _a;
164
166
  var _this = this;
167
+ var _b;
165
168
  if (opentelemetry === void 0) { opentelemetry = {
166
169
  inheritFrom: 'event',
170
+ tracer: OpenTelemetry_1.ArvoEventHandlerTracer,
167
171
  }; }
168
- return __generator(this, function (_b) {
169
- switch (_b.label) {
172
+ return __generator(this, function (_c) {
173
+ switch (_c.label) {
170
174
  case 0:
171
175
  spanName = "ArvoEventHandler<".concat(this.contract.uri, ">.execute<").concat(event.type, ">");
172
176
  spanKinds = {
@@ -182,8 +186,8 @@ var ArvoEventHandler = /** @class */ (function (_super) {
182
186
  _a),
183
187
  };
184
188
  span = opentelemetry.inheritFrom === 'event'
185
- ? (0, utils_2.createSpanFromEvent)(spanName, event, spanKinds)
186
- : OpenTelemetry_1.ArvoEventHandlerTracer.startSpan(spanName, spanOptions);
189
+ ? (0, utils_2.createSpanFromEvent)(spanName, event, spanKinds, opentelemetry.tracer)
190
+ : ((_b = opentelemetry.tracer) !== null && _b !== void 0 ? _b : OpenTelemetry_1.ArvoEventHandlerTracer).startSpan(spanName, spanOptions);
187
191
  eventFactory = (0, arvo_core_1.createArvoEventFactory)(this.contract);
188
192
  return [4 /*yield*/, api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), function () { return __awaiter(_this, void 0, void 0, function () {
189
193
  var otelSpanHeaders, inputEventValidation, _handleOutput, outputs, error_1, result;
@@ -257,7 +261,7 @@ var ArvoEventHandler = /** @class */ (function (_super) {
257
261
  }
258
262
  });
259
263
  }); })];
260
- case 1: return [2 /*return*/, _b.sent()];
264
+ case 1: return [2 /*return*/, _c.sent()];
261
265
  }
262
266
  });
263
267
  });
@@ -3,6 +3,7 @@ import ArvoEventHandler from '../ArvoEventHandler';
3
3
  import { IArvoEventRouter } from './types';
4
4
  import { SpanKind } from '@opentelemetry/api';
5
5
  import AbstractArvoEventHandler from '../AbstractArvoEventHandler';
6
+ import { ExecutionOpenTelemetryConfiguration } from '../AbstractArvoEventHandler/types';
6
7
  /**
7
8
  * ArvoEventRouter class handles routing of ArvoEvents to appropriate event handlers.
8
9
  */
@@ -48,6 +49,8 @@ export declare class ArvoEventRouter extends AbstractArvoEventHandler {
48
49
  * Executes the routing process for a given ArvoEvent.
49
50
  *
50
51
  * @param event - The ArvoEvent to be processed and routed.
52
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
53
+ * and context inheritance settings.
51
54
  * @returns A Promise that resolves to an array of ArvoEvents.
52
55
  *
53
56
  * @remarks
@@ -89,7 +92,7 @@ export declare class ArvoEventRouter extends AbstractArvoEventHandler {
89
92
  * - Execution units are tracked for both successful executions and errors.
90
93
  * - The router's default execution units are used for error events.
91
94
  */
92
- execute(event: ArvoEvent): Promise<ArvoEvent[]>;
95
+ execute(event: ArvoEvent, opentelemetry?: ExecutionOpenTelemetryConfiguration): Promise<ArvoEvent[]>;
93
96
  /**
94
97
  * Provides the schema for system error events.
95
98
  *
@@ -61,6 +61,7 @@ var api_1 = require("@opentelemetry/api");
61
61
  var utils_2 = require("./utils");
62
62
  var utils_3 = require("../OpenTelemetry/utils");
63
63
  var AbstractArvoEventHandler_1 = __importDefault(require("../AbstractArvoEventHandler"));
64
+ var OpenTelemetry_1 = require("../OpenTelemetry");
64
65
  /**
65
66
  * ArvoEventRouter class handles routing of ArvoEvents to appropriate event handlers.
66
67
  */
@@ -122,6 +123,8 @@ var ArvoEventRouter = /** @class */ (function (_super) {
122
123
  * Executes the routing process for a given ArvoEvent.
123
124
  *
124
125
  * @param event - The ArvoEvent to be processed and routed.
126
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
127
+ * and context inheritance settings.
125
128
  * @returns A Promise that resolves to an array of ArvoEvents.
126
129
  *
127
130
  * @remarks
@@ -163,19 +166,35 @@ var ArvoEventRouter = /** @class */ (function (_super) {
163
166
  * - Execution units are tracked for both successful executions and errors.
164
167
  * - The router's default execution units are used for error events.
165
168
  */
166
- ArvoEventRouter.prototype.execute = function (event) {
167
- return __awaiter(this, void 0, void 0, function () {
168
- var span;
169
- var _this = this;
169
+ ArvoEventRouter.prototype.execute = function (event_1) {
170
+ return __awaiter(this, arguments, void 0, function (event, opentelemetry) {
171
+ var spanName, spanKinds, spanOptions, span;
170
172
  var _a;
171
- return __generator(this, function (_b) {
172
- switch (_b.label) {
173
+ var _this = this;
174
+ var _b, _c;
175
+ if (opentelemetry === void 0) { opentelemetry = {
176
+ inheritFrom: 'event',
177
+ tracer: OpenTelemetry_1.ArvoEventHandlerTracer,
178
+ }; }
179
+ return __generator(this, function (_d) {
180
+ switch (_d.label) {
173
181
  case 0:
174
- span = (0, utils_3.createSpanFromEvent)("ArvoEventRouter.source<".concat((_a = this._source) !== null && _a !== void 0 ? _a : 'arvo.event.router', ">.execute<").concat(event.type, ">"), event, {
182
+ spanName = "ArvoEventRouter.source<".concat((_b = this._source) !== null && _b !== void 0 ? _b : 'arvo.event.router', ">.execute<").concat(event.type, ">");
183
+ spanKinds = {
175
184
  kind: this.openTelemetrySpanKind,
176
185
  openInference: this.openInferenceSpanKind,
177
186
  arvoExecution: this.arvoExecutionSpanKind,
178
- });
187
+ };
188
+ spanOptions = {
189
+ kind: spanKinds.kind,
190
+ attributes: (_a = {},
191
+ _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = spanKinds.openInference,
192
+ _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = spanKinds.arvoExecution,
193
+ _a),
194
+ };
195
+ span = opentelemetry.inheritFrom === 'event'
196
+ ? (0, utils_3.createSpanFromEvent)(spanName, event, spanKinds, opentelemetry.tracer)
197
+ : ((_c = opentelemetry.tracer) !== null && _c !== void 0 ? _c : OpenTelemetry_1.ArvoEventHandlerTracer).startSpan(spanName, spanOptions);
179
198
  return [4 /*yield*/, api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), function () { return __awaiter(_this, void 0, void 0, function () {
180
199
  var otelSpanHeaders, newEvent, results, error_1;
181
200
  var _this = this;
@@ -195,7 +214,7 @@ var ArvoEventRouter = /** @class */ (function (_super) {
195
214
  if (!this.handlersMap[newEvent.type]) {
196
215
  throw new Error((0, arvo_core_1.cleanString)("\n Invalid event (type=".concat(newEvent.type, "). No valid handler \n <handler[*].contract.accepts.type> found in the router.\n ")));
197
216
  }
198
- return [4 /*yield*/, this.handlersMap[newEvent.type].execute(newEvent)];
217
+ return [4 /*yield*/, this.handlersMap[newEvent.type].execute(newEvent, { inheritFrom: 'execution', tracer: opentelemetry.tracer })];
199
218
  case 2:
200
219
  results = _a.sent();
201
220
  return [2 /*return*/, results.map(function (event) {
@@ -233,7 +252,7 @@ var ArvoEventRouter = /** @class */ (function (_super) {
233
252
  }
234
253
  });
235
254
  }); })];
236
- case 1: return [2 /*return*/, _b.sent()];
255
+ case 1: return [2 /*return*/, _d.sent()];
237
256
  }
238
257
  });
239
258
  });
@@ -2,6 +2,7 @@ import { SpanKind } from '@opentelemetry/api';
2
2
  import { ArvoEvent, ArvoExecutionSpanKind, OpenInferenceSpanKind } from 'arvo-core';
3
3
  import { IMultiArvoEventHandler } from './types';
4
4
  import AbstractArvoEventHandler from '../AbstractArvoEventHandler';
5
+ import { ExecutionOpenTelemetryConfiguration } from '../AbstractArvoEventHandler/types';
5
6
  /**
6
7
  * Represents a Multi ArvoEvent handler that can process multiple event types.
7
8
  *
@@ -41,6 +42,8 @@ export default class MultiArvoEventHandler extends AbstractArvoEventHandler {
41
42
  * Executes the event handler for a given event.
42
43
  *
43
44
  * @param event - The event to handle.
45
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
46
+ * and context inheritance settings.
44
47
  * @returns A promise that resolves to an array of resulting ArvoEvents.
45
48
  *
46
49
  * @remarks
@@ -90,9 +93,7 @@ export default class MultiArvoEventHandler extends AbstractArvoEventHandler {
90
93
  * - If they don't match, an error is thrown with a descriptive message.
91
94
  * - This ensures that the handler only processes events intended for it.
92
95
  */
93
- execute(event: ArvoEvent, opentelemetry?: {
94
- inheritFrom: 'event' | 'execution';
95
- }): Promise<ArvoEvent[]>;
96
+ execute(event: ArvoEvent, opentelemetry?: ExecutionOpenTelemetryConfiguration): Promise<ArvoEvent[]>;
96
97
  /**
97
98
  * Provides the schema for system error events.
98
99
  *
@@ -101,6 +101,8 @@ var MultiArvoEventHandler = /** @class */ (function (_super) {
101
101
  * Executes the event handler for a given event.
102
102
  *
103
103
  * @param event - The event to handle.
104
+ * @param opentelemetry - Configuration for OpenTelemetry integration, including tracing options
105
+ * and context inheritance settings.
104
106
  * @returns A promise that resolves to an array of resulting ArvoEvents.
105
107
  *
106
108
  * @remarks
@@ -155,11 +157,13 @@ var MultiArvoEventHandler = /** @class */ (function (_super) {
155
157
  var spanName, spanKinds, spanOptions, span;
156
158
  var _a;
157
159
  var _this = this;
160
+ var _b;
158
161
  if (opentelemetry === void 0) { opentelemetry = {
159
162
  inheritFrom: 'event',
163
+ tracer: OpenTelemetry_1.ArvoEventHandlerTracer,
160
164
  }; }
161
- return __generator(this, function (_b) {
162
- switch (_b.label) {
165
+ return __generator(this, function (_c) {
166
+ switch (_c.label) {
163
167
  case 0:
164
168
  spanName = "MutliArvoEventHandler.source<".concat(this.source, ">.execute<").concat(event.type, ">");
165
169
  spanKinds = {
@@ -175,8 +179,8 @@ var MultiArvoEventHandler = /** @class */ (function (_super) {
175
179
  _a),
176
180
  };
177
181
  span = opentelemetry.inheritFrom === 'event'
178
- ? (0, utils_2.createSpanFromEvent)(spanName, event, spanKinds)
179
- : OpenTelemetry_1.ArvoEventHandlerTracer.startSpan(spanName, spanOptions);
182
+ ? (0, utils_2.createSpanFromEvent)(spanName, event, spanKinds, opentelemetry.tracer)
183
+ : ((_b = opentelemetry.tracer) !== null && _b !== void 0 ? _b : OpenTelemetry_1.ArvoEventHandlerTracer).startSpan(spanName, spanOptions);
180
184
  return [4 /*yield*/, api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), function () { return __awaiter(_this, void 0, void 0, function () {
181
185
  var otelSpanHeaders, _handlerOutput, outputs, error_1;
182
186
  return __generator(this, function (_a) {
@@ -232,7 +236,7 @@ var MultiArvoEventHandler = /** @class */ (function (_super) {
232
236
  }
233
237
  });
234
238
  }); })];
235
- case 1: return [2 /*return*/, _b.sent()];
239
+ case 1: return [2 /*return*/, _c.sent()];
236
240
  }
237
241
  });
238
242
  });
package/dist/index.d.ts CHANGED
@@ -11,4 +11,5 @@ import { ArvoEventRouter } from './ArvoEventRouter';
11
11
  import { createArvoEventRouter } from './ArvoEventRouter/helpers';
12
12
  import AbstractArvoEventHandler from './AbstractArvoEventHandler';
13
13
  import { createSpanFromEvent } from './OpenTelemetry/utils';
14
- export { ArvoEventHandler, createArvoEventHandler, IArvoEventHandler, ArvoEventHandlerFunctionOutput, ArvoEventHandlerFunctionInput, ArvoEventHandlerFunction, PartialExcept, MultiArvoEventHandler, MultiArvoEventHandlerFunctionInput, MultiArvoEventHandlerFunctionOutput, MultiArvoEventHandlerFunction, IMultiArvoEventHandler, createMultiArvoEventHandler, isNullOrUndefined, getValueOrDefault, coalesce, coalesceOrDefault, IArvoEventRouter, ArvoEventRouter, createArvoEventRouter, AbstractArvoEventHandler, createSpanFromEvent as createOtelSpanFromEvent, };
14
+ import { ExecutionOpenTelemetryConfiguration } from './AbstractArvoEventHandler/types';
15
+ export { ArvoEventHandler, createArvoEventHandler, IArvoEventHandler, ArvoEventHandlerFunctionOutput, ArvoEventHandlerFunctionInput, ArvoEventHandlerFunction, PartialExcept, MultiArvoEventHandler, MultiArvoEventHandlerFunctionInput, MultiArvoEventHandlerFunctionOutput, MultiArvoEventHandlerFunction, IMultiArvoEventHandler, createMultiArvoEventHandler, isNullOrUndefined, getValueOrDefault, coalesce, coalesceOrDefault, IArvoEventRouter, ArvoEventRouter, createArvoEventRouter, AbstractArvoEventHandler, createSpanFromEvent as createOtelSpanFromEvent, ExecutionOpenTelemetryConfiguration, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arvo-event-handler",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "This package contains class and function for event handlers in an Arvo Event Driven system",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {