arvo-core
Version:
This core package contains all the core classes and components of the Arvo Event Driven System
203 lines (202 loc) • 11 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var helpers_1 = require("../ArvoEvent/helpers");
var schema_1 = require("../ArvoEvent/schema");
var ArvoOrchestrationSubject_1 = __importDefault(require("../ArvoOrchestrationSubject"));
var OpenTelemetry_1 = require("../OpenTelemetry");
var utils_1 = require("../utils");
var utils_2 = require("./utils");
/**
* Factory class for creating and validating events based on a versioned Arvo contract.
* Handles event creation, validation, and OpenTelemetry integration for a specific
* contract version.
*
* @example
* ```typescript
* const contract = createArvoContract({
* uri: 'example/api',
* type: 'user.create',
* versions: { '1.0.0': { ... } }
* });
*
* const factory = createArvoEventFactory(contract.version('1.0.0'));
* ```
*/
var ArvoEventFactory = /** @class */ (function () {
/**
* Creates an ArvoEventFactory instance for a specific version of a contract.
*
* @param contract - The versioned contract to use for event creation and validation
*/
function ArvoEventFactory(contract) {
this._name = 'ArvoEventFactory';
this.contract = contract;
}
/**
* Creates and validates an event matching the contract's accept specification.
*
* @param event - The event configuration object
* @param [extensions] - Optional additional properties for the event
*
* @returns A validated ArvoEvent matching the contract's accept specification
*
* @throws {Error} If validation fails or OpenTelemetry operations fail
*
* @example
* ```typescript
* const event = factory.accepts({
* source: 'api/users',
* data: { name: 'John', email: 'john@example.com' }
* });
* ```
*/
ArvoEventFactory.prototype.accepts = function (event, extensions) {
var _this = this;
return OpenTelemetry_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
name: "".concat(this._name, ".accepts"),
spanOptions: (0, utils_2.createSpanOptions)(this.contract),
fn: function (span) {
var _a, _b, _c, _d, _e, _f, _g;
var otelHeaders = (0, OpenTelemetry_1.currentOpenTelemetryHeaders)();
var validationResult = _this.contract.accepts.schema.safeParse(event.data);
if (!validationResult.success) {
throw new Error("Accept Event data validation failed: ".concat(validationResult.error.message));
}
var eventType = _this.contract.accepts.type;
var eventSubject = (_a = event.subject) !== null && _a !== void 0 ? _a : ArvoOrchestrationSubject_1.default.new({
initiator: event.source,
version: _this.contract.version,
orchestator: _this.contract.accepts.type,
meta: event.redirectto
? {
redirectto: event.redirectto,
}
: undefined,
});
var generatedEvent = (0, helpers_1.createArvoEvent)(__assign(__assign({}, event), { subject: eventSubject, traceparent: (_c = (_b = event.traceparent) !== null && _b !== void 0 ? _b : otelHeaders.traceparent) !== null && _c !== void 0 ? _c : undefined, tracestate: (_e = (_d = event.tracestate) !== null && _d !== void 0 ? _d : otelHeaders.tracestate) !== null && _e !== void 0 ? _e : undefined, type: eventType, datacontenttype: schema_1.ArvoDataContentType, dataschema: utils_1.EventDataschemaUtil.create(_this.contract), data: validationResult.data, domain: event.domain === null ? undefined : ((_g = (_f = event.domain) !== null && _f !== void 0 ? _f : _this.contract.domain) !== null && _g !== void 0 ? _g : undefined) }), extensions, { disable: true });
span.setAttributes(generatedEvent.otelAttributes);
return generatedEvent;
},
});
};
/**
* Creates and validates an event matching one of the contract's emit specifications.
*
* @param event - The event configuration object
* @param [extensions] - Optional additional properties for the event
*
* @returns A validated ArvoEvent matching the specified emit type
*
* @throws {Error} If validation fails, emit type doesn't exist, or OpenTelemetry operations fail
*
* @example
* ```typescript
* const event = factory.emits({
* type: 'user.created',
* source: 'api/users',
* data: { id: '123', timestamp: new Date() }
* });
* ```
*/
ArvoEventFactory.prototype.emits = function (event, extensions) {
var _this = this;
return OpenTelemetry_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
name: "".concat(this._name, ".emits<").concat(event.type, ">"),
spanOptions: (0, utils_2.createSpanOptions)(this.contract),
fn: function (span) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
var otelHeaders = (0, OpenTelemetry_1.currentOpenTelemetryHeaders)();
var validationResult = (_b = (_a = _this.contract.emits) === null || _a === void 0 ? void 0 : _a[event.type]) === null || _b === void 0 ? void 0 : _b.safeParse(event.data);
if (!(validationResult === null || validationResult === void 0 ? void 0 : validationResult.success)) {
var msg = (_d = (_c = validationResult === null || validationResult === void 0 ? void 0 : validationResult.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : "No contract available for ".concat(event.type);
throw new Error("Emit Event data validation failed: ".concat(msg));
}
var eventSubject = (_e = event.subject) !== null && _e !== void 0 ? _e : ArvoOrchestrationSubject_1.default.new({
initiator: event.source,
version: _this.contract.version,
orchestator: event.type,
meta: event.redirectto
? {
redirectto: event.redirectto,
}
: undefined,
});
var generatedEvent = (0, helpers_1.createArvoEvent)(__assign(__assign({}, event), { subject: eventSubject, traceparent: (_g = (_f = event.traceparent) !== null && _f !== void 0 ? _f : otelHeaders.traceparent) !== null && _g !== void 0 ? _g : undefined, tracestate: (_j = (_h = event.tracestate) !== null && _h !== void 0 ? _h : otelHeaders.tracestate) !== null && _j !== void 0 ? _j : undefined, datacontenttype: schema_1.ArvoDataContentType, dataschema: utils_1.EventDataschemaUtil.create(_this.contract), data: validationResult.data, domain: event.domain === null ? undefined : ((_l = (_k = event.domain) !== null && _k !== void 0 ? _k : _this.contract.domain) !== null && _l !== void 0 ? _l : undefined) }), extensions, { disable: true });
span.setAttributes(generatedEvent.otelAttributes);
return generatedEvent;
},
});
};
/**
* Creates a system error event for error reporting and handling.
*
* @param event - The error event configuration
* @param event.error - The Error instance to convert to an event
* @param [extensions] - Optional additional properties for the event
*
* @returns A system error ArvoEvent
*
* @throws {Error} If event creation or OpenTelemetry operations fail
*
* @example
* ```typescript
* const errorEvent = factory.systemError({
* error: new Error('Validation failed'),
* source: 'api/validation'
* });
* ```
*/
ArvoEventFactory.prototype.systemError = function (event, extensions) {
var _this = this;
return OpenTelemetry_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
name: "".concat(this._name, ".systemError"),
spanOptions: (0, utils_2.createSpanOptions)(this.contract),
fn: function (span) {
var _a, _b, _c, _d, _e, _f, _g;
var otelHeaders = (0, OpenTelemetry_1.currentOpenTelemetryHeaders)();
var error = event.error, _event = __rest(event, ["error"]);
var eventType = _this.contract.systemError.type;
var eventSubject = (_a = event.subject) !== null && _a !== void 0 ? _a : ArvoOrchestrationSubject_1.default.new({
initiator: event.source,
version: _this.contract.version,
orchestator: eventType,
meta: event.redirectto
? {
redirectto: event.redirectto,
}
: undefined,
});
var generatedEvent = (0, helpers_1.createArvoEvent)(__assign(__assign({}, _event), { subject: eventSubject, traceparent: (_c = (_b = event.traceparent) !== null && _b !== void 0 ? _b : otelHeaders.traceparent) !== null && _c !== void 0 ? _c : undefined, tracestate: (_e = (_d = event.tracestate) !== null && _d !== void 0 ? _d : otelHeaders.tracestate) !== null && _e !== void 0 ? _e : undefined, type: eventType, data: (0, utils_1.createArvoError)(error), datacontenttype: schema_1.ArvoDataContentType, dataschema: utils_1.EventDataschemaUtil.createWithWildCardVersion(_this.contract), domain: event.domain === null ? undefined : ((_g = (_f = event.domain) !== null && _f !== void 0 ? _f : _this.contract.domain) !== null && _g !== void 0 ? _g : undefined) }), extensions, { disable: true });
span.setAttributes(generatedEvent.otelAttributes);
return generatedEvent;
},
});
};
return ArvoEventFactory;
}());
exports.default = ArvoEventFactory;