arvo-core
Version:
This core package contains all the core classes and components of the Arvo Event Driven System
317 lines (316 loc) • 14.3 kB
JavaScript
"use strict";
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
var OpenTelemetry_1 = require("../OpenTelemetry");
var schema_1 = require("./schema");
/**
* Represents an ArvoEvent, which extends the CloudEvent specification with
* Arvo-specific extensions for event routing, access control, execution metrics,
* and OpenTelemetry distributed tracing support.
*/
var ArvoEvent = /** @class */ (function () {
/**
* Creates an instance of ArvoEvent with CloudEvent context, data, and optional extensions.
*
* @param context - The CloudEvent context combined with required Arvo and OpenTelemetry extensions
* @param data - The event data payload (must be JSON serializable)
* @param extensions - Optional additional custom extensions with lowercase alphanumeric keys
*
* @throws {Error} If datacontenttype is "application/cloudevents+json;charset=UTF-8;profile=arvo" but the 'to' field is not defined
* @throws {Error} If any validation fails according to the respective schemas
*
* @example
* ```typescript
* const event = new ArvoEvent(
* {
* id: 'event-123',
* source: 'https://example.com/service',
* type: 'com.example.user.created',
* subject: 'https://example.com/users/123',
* time: new Date().toISOString(),
* specversion: '1.0',
* datacontenttype: 'application/cloudevents+json;charset=UTF-8;profile=arvo',
* dataschema: null,
* to: 'com.example.user.processor',
* accesscontrol: 'role:admin;department:hr',
* redirectto: null,
* executionunits: 10,
* parentid: 'parent-event-456',
* domain: 'analytics',
* traceparent: '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01',
* tracestate: 'vendor=trace-data'
* },
* { userId: '123', name: 'John Doe' }
* );
* ```
*/
function ArvoEvent(context, data, extensions) {
var cloudEventContext = schema_1.CloudEventContextSchema.parse(context);
this.id = cloudEventContext.id;
this.time = cloudEventContext.time;
this.type = cloudEventContext.type;
this.subject = cloudEventContext.subject;
this.source = cloudEventContext.source;
this.datacontenttype = cloudEventContext.datacontenttype;
this.specversion = cloudEventContext.specversion;
this.dataschema = cloudEventContext.dataschema;
this.data = schema_1.ArvoDataSchema.parse(data);
var arvoExtension = schema_1.ArvoExtensionSchema.parse(context);
var otelExtension = schema_1.OpenTelemetryExtensionSchema.parse(context);
this._extensions = __assign(__assign({}, (extensions ? schema_1.CloudEventExtensionSchema.parse(extensions) : {})), { to: arvoExtension.to, accesscontrol: arvoExtension.accesscontrol, redirectto: arvoExtension.redirectto, executionunits: arvoExtension.executionunits, traceparent: otelExtension.traceparent, tracestate: otelExtension.tracestate, parentid: arvoExtension.parentid, domain: arvoExtension.domain });
if (this.datacontenttype === schema_1.ArvoDataContentType) {
if (!this._extensions.to) {
throw new Error("The ArvoEvent must have a non-empty 'to' field");
}
}
Object.freeze(this);
Object.freeze(this._extensions);
}
Object.defineProperty(ArvoEvent.prototype, "cloudevent", {
/**
* Gets the CloudEvent-specified fields separated into default attributes and extensions.
*
* @returns An object containing:
* - `default`: Standard CloudEvent attributes (id, source, specversion, type, subject, datacontenttype, dataschema, data, time)
* - `extensions`: All extension attributes including:
* - Arvo extensions
* - OpenTelemetry extensions
* - Custom extensions
*
* @example
* ```typescript
* const { default: defaults, extensions } = event.cloudevent;
* console.log(defaults.id); // Event ID
* console.log(extensions.to); // Arvo 'to' field
* ```
*/
get: function () {
return {
default: {
id: this.id,
source: this.source,
specversion: this.specversion,
type: this.type,
subject: this.subject,
datacontenttype: this.datacontenttype,
dataschema: this.dataschema,
data: this.data,
time: this.time,
},
extensions: __assign({}, this._extensions),
};
},
enumerable: false,
configurable: true
});
/**
* Converts the ArvoEvent to a JSON-serializable object by combining
* all CloudEvent default fields with all extensions into a single flat object.
*
* @returns A flat object containing all CloudEvent fields and extensions,
* suitable for JSON serialization and network transmission
*
* @remarks
* This method creates a flattened representation where both standard CloudEvent
* fields and all extensions (Arvo, OpenTelemetry, and custom) are at the same level.
* For separated access to defaults and extensions, use the `cloudevent` getter instead.
*
* @example
* ```typescript
* const jsonObj = event.toJSON();
* // Contains: id, source, type, subject, data, time, to, traceparent, etc.
* ```
*/
ArvoEvent.prototype.toJSON = function () {
return __assign(__assign({}, this.cloudevent.default), this._extensions);
};
/**
* Converts the ArvoEvent to a JSON string representation.
*
* @param spacing - The number of spaces to use for indentation (default: 0 for compact output)
* @returns A JSON string representation of the complete ArvoEvent
*
* @example
* ```typescript
* const compactJson = event.toString(); // Compact JSON
* const prettyJson = event.toString(2); // Pretty-printed with 2-space indentation
* ```
*/
ArvoEvent.prototype.toString = function (spacing) {
if (spacing === void 0) { spacing = 0; }
return JSON.stringify(this.toJSON(), null, spacing);
};
Object.defineProperty(ArvoEvent.prototype, "otelAttributes", {
/**
* Gets OpenTelemetry attributes derived from the ArvoEvent for distributed tracing.
*
* @returns An object containing OpenTelemetry semantic convention attributes:
* - Standard CloudEvent attributes prefixed with 'cloudevents.event_*'
* - Arvo-specific attributes prefixed with 'cloudevents.arvo.*'
* - Uses 'N/A' for undefined/null values to maintain telemetry consistency
*
* @remarks
* The attributes follow the OpenTelemetry semantic conventions for CloudEvents
* as specified in the official documentation:
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/cloudevents/
*/
get: function () {
var _a, _b, _c, _d, _e, _f;
return {
'cloudevents.event_id': this.id || OpenTelemetry_1.OTelNull,
'cloudevents.event_source': this.source || OpenTelemetry_1.OTelNull,
'cloudevents.event_spec_version': this.specversion || OpenTelemetry_1.OTelNull,
'cloudevents.event_subject': this.subject || OpenTelemetry_1.OTelNull,
'cloudevents.event_type': this.type || OpenTelemetry_1.OTelNull,
'cloudevents.event_time': this.time || OpenTelemetry_1.OTelNull,
'cloudevents.event_datacontenttype': this.datacontenttype || OpenTelemetry_1.OTelNull,
'cloudevents.event_dataschema': (_a = this.dataschema) !== null && _a !== void 0 ? _a : OpenTelemetry_1.OTelNull,
'cloudevents.arvo.event_redirectto': (_b = this._extensions.redirectto) !== null && _b !== void 0 ? _b : OpenTelemetry_1.OTelNull,
'cloudevents.arvo.event_to': (_c = this._extensions.to) !== null && _c !== void 0 ? _c : OpenTelemetry_1.OTelNull,
'cloudevents.arvo.event_executionunits': (_d = this._extensions.executionunits) !== null && _d !== void 0 ? _d : OpenTelemetry_1.OTelNull,
'cloudevents.arvo.event_parentid': (_e = this._extensions.parentid) !== null && _e !== void 0 ? _e : OpenTelemetry_1.OTelNull,
'cloudevents.arvo.event_domain': (_f = this._extensions.domain) !== null && _f !== void 0 ? _f : OpenTelemetry_1.OTelNull,
};
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "to", {
/**
* Gets the target consumer machine for event routing.
*/
get: function () {
return this._extensions.to;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "accesscontrol", {
/**
* Gets the access control information for the event.
* Can contain:
* - A UserID (valid UUID)
* - An encrypted base64 string with access control data
* - Key-value pairs (semicolon-separated, colon-delimited)
* Example: "role:admin;department:finance;clearance:top-secret"
*/
get: function () {
return this._extensions.accesscontrol;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "redirectto", {
/**
* Gets the alternative recipient or destination for dynamic routing.
* Enables complex workflows and conditional event routing.
*/
get: function () {
return this._extensions.redirectto;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "executionunits", {
/**
* Gets the execution units representing the cost associated with
* generating this event. Used for tracking financial impact and
* resource utilization in cloud-based systems.
*/
get: function () {
return this._extensions.executionunits;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "traceparent", {
/**
* Gets the OpenTelemetry traceparent header containing trace context
* information including trace ID, parent span ID, and trace flags
* for distributed tracing across services.
*/
get: function () {
return this._extensions.traceparent;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "tracestate", {
/**
* Gets the OpenTelemetry tracestate header containing vendor-specific
* trace information as key-value pairs propagated alongside traceparent
* in distributed tracing scenarios.
*/
get: function () {
return this._extensions.tracestate;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "parentid", {
/**
* Gets the unique identifier of the event that directly triggered
* the creation of this event within the Arvo ecosystem.
* Establishes direct causal relationships for event lineage tracking.
* Null indicates an initiating event or generation outside direct causation.
*/
get: function () {
return this._extensions.parentid;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "domain", {
/**
* Gets the processing domain for event routing and workflow orchestration.
*/
get: function () {
return this._extensions.domain;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ArvoEvent.prototype, "extensions", {
/**
* Gets only the custom extensions (TExtension) added to the ArvoEvent,
* excluding the standard Arvo and OpenTelemetry extensions.
*
* @returns The custom extensions object with Arvo and OpenTelemetry fields removed
*
* @remarks
* For accessing all extensions including Arvo and OpenTelemetry, use `cloudevent.extensions`.
* For accessing basic CloudEvent fields, use `cloudevent.default`.
* Custom extension keys must follow lowercase alphanumeric naming (a-z, 0-9 only).
*/
get: function () {
var _a = this
._extensions, traceparent = _a.traceparent, tracestate = _a.tracestate, to = _a.to, redirectto = _a.redirectto, accesscontrol = _a.accesscontrol, executionunits = _a.executionunits, parentid = _a.parentid, domain = _a.domain, rest = __rest(_a, ["traceparent", "tracestate", "to", "redirectto", "accesscontrol", "executionunits", "parentid", "domain"]);
return rest;
},
enumerable: false,
configurable: true
});
return ArvoEvent;
}());
exports.default = ArvoEvent;