arvo-event-handler 3.0.23 → 3.0.25

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,4 @@
1
- import type { ArvoEvent, VersionedArvoContract } from 'arvo-core';
1
+ import { type ArvoEvent, type VersionedArvoContract } from 'arvo-core';
2
2
  /**
3
3
  * Symbolic constants for domain resolution in Arvo event emission.
4
4
  *
@@ -7,57 +7,75 @@ import type { ArvoEvent, VersionedArvoContract } from 'arvo-core';
7
7
  */
8
8
  export declare const ArvoDomain: {
9
9
  /**
10
- * Resolve the domain from the emitting handlers own contract (`handlerSelfContract.domain`).
10
+ * Resolve domain from the handler's contract.
11
11
  *
12
- * Use this when the handler’s contract defines a stable domain that should apply
13
- * to all emitted events, regardless of the triggering context.
12
+ * Uses `handlerSelfContract.domain` for all emitted events.
14
13
  */
15
14
  readonly FROM_SELF_CONTRACT: "domain.contract.self.inherit";
16
15
  /**
17
- * Resolve the domain from the contract that defines the event being emitted (`eventContract.domain`).
16
+ * Resolve domain from the event's contract.
18
17
  *
19
- * In `ArvoResumable` and `ArvoMachine`, this is typically used when emitting service events
20
- * (not the completion event). In `ArvoEventHandler`, where only the self contract exists,
21
- * this resolves to the same value as `FROM_SELF_CONTRACT`.
22
- *
23
- * For orchestration `complete` events, this behaves identically to `FROM_SELF_CONTRACT`
24
- * since the emitting contract is also the self contract.
18
+ * For orchestrators, uses the service contract's domain.
19
+ * For handlers, behaves the same as FROM_SELF_CONTRACT.
25
20
  */
26
21
  readonly FROM_EVENT_CONTRACT: "domain.contract.inherit";
27
22
  /**
28
- * Resolve the domain from the triggering events `domain` field (`triggeringEvent.domain`).
23
+ * Resolve domain from the triggering event's domain field.
29
24
  *
30
- * Use this when you want to preserve the domain context of the incoming event
31
- * and carry it forward through event emissions.
25
+ * Preserves the domain context of the incoming event.
32
26
  */
33
27
  readonly FROM_TRIGGERING_EVENT: "domain.event.inherit";
34
28
  /**
35
- * Keep the event in the current execution context (null domain).
29
+ * Extract domain from the current event's subject.
30
+ *
31
+ * Parses the subject to retrieve `execution.domain`.
32
+ * Falls back to LOCAL if subject is not a valid ArvoOrchestrationSubject.
33
+ */
34
+ readonly FROM_CURRENT_SUBJECT: "domain.event.current.subject";
35
+ /**
36
+ * Extract domain from the parent orchestration subject.
37
+ *
38
+ * Parses the parent subject to retrieve `execution.domain`.
39
+ * Falls back to LOCAL if subject is not a valid ArvoOrchestrationSubject.
40
+ */
41
+ readonly FROM_PARENT_SUBJECT: "domain.parent.subject";
42
+ /**
43
+ * Resolve domain based on orchestration context.
44
+ *
45
+ * Routes responses and completions back through the orchestration chain:
46
+ * - For handlers: routes back to the orchestration's domain
47
+ * - For child orchestrations: routes to parent's domain if different, LOCAL if same
48
+ * - For root orchestrations: routes to own domain if cross-domain call, LOCAL otherwise
49
+ *
50
+ * This is the recommended default for maintaining domain coherence in orchestration workflows.
51
+ */
52
+ readonly ORCHESTRATION_CONTEXT: "domain.orchestration.context";
53
+ /**
54
+ * Stay in the current execution context (null domain).
36
55
  *
37
- * Use this when the event should remain local to the current domain without
38
- * crossing execution boundaries through the exchange layer.
56
+ * Event remains local without crossing domain boundaries.
39
57
  */
40
58
  readonly LOCAL: null;
41
59
  };
42
60
  /**
43
- * Resolves a symbolic or static domain value into a concrete domain string or `null`.
61
+ * Resolves symbolic domain constants to concrete domain values.
44
62
  *
45
- * Used internally in the Arvo execution model to interpret symbolic domain constants
46
- * at the moment an event is emitted. Supports resolution from:
47
- * - the emitting handler's own contract
48
- * - the emitted event’s associated contract
49
- * - the triggering event’s `domain` field
63
+ * Interprets domain resolution symbols and returns the appropriate domain string or null.
64
+ * Static domain strings pass through unchanged.
50
65
  *
51
- * @param param - Parameters for resolving the domain.
52
- * @param param.domainToResolve - Either a static domain string, symbolic value, or null.
53
- * @param param.handlerSelfContract - The contract of the handler currently emitting the event.
54
- * @param param.eventContract - The contract of the event being emitted (optional).
55
- * @param param.triggeringEvent - The triggering event that caused this emission.
66
+ * @param param.domainToResolve - Domain string or symbolic constant to resolve
67
+ * @param param.parentSubject - Parent orchestration subject (null for root orchestrations or handlers)
68
+ * @param param.currentSubject - Current event subject
69
+ * @param param.handlerSelfContract - Contract of the handler emitting the event
70
+ * @param param.eventContract - Contract of the event being emitted (optional)
71
+ * @param param.triggeringEvent - Event that triggered this emission
56
72
  *
57
- * @returns A resolved domain string, or `null` if no valid domain is found.
73
+ * @returns Resolved domain string or null
58
74
  */
59
75
  export declare const resolveEventDomain: (param: {
60
76
  domainToResolve: string | null;
77
+ parentSubject: string | null;
78
+ currentSubject: string;
61
79
  handlerSelfContract: VersionedArvoContract<any, any>;
62
80
  eventContract: VersionedArvoContract<any, any> | null;
63
81
  triggeringEvent: ArvoEvent;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveEventDomain = exports.ArvoDomain = void 0;
4
+ var arvo_core_1 = require("arvo-core");
4
5
  /**
5
6
  * Symbolic constants for domain resolution in Arvo event emission.
6
7
  *
@@ -9,70 +10,138 @@ exports.resolveEventDomain = exports.ArvoDomain = void 0;
9
10
  */
10
11
  exports.ArvoDomain = {
11
12
  /**
12
- * Resolve the domain from the emitting handlers own contract (`handlerSelfContract.domain`).
13
+ * Resolve domain from the handler's contract.
13
14
  *
14
- * Use this when the handler’s contract defines a stable domain that should apply
15
- * to all emitted events, regardless of the triggering context.
15
+ * Uses `handlerSelfContract.domain` for all emitted events.
16
16
  */
17
17
  FROM_SELF_CONTRACT: 'domain.contract.self.inherit',
18
18
  /**
19
- * Resolve the domain from the contract that defines the event being emitted (`eventContract.domain`).
19
+ * Resolve domain from the event's contract.
20
20
  *
21
- * In `ArvoResumable` and `ArvoMachine`, this is typically used when emitting service events
22
- * (not the completion event). In `ArvoEventHandler`, where only the self contract exists,
23
- * this resolves to the same value as `FROM_SELF_CONTRACT`.
24
- *
25
- * For orchestration `complete` events, this behaves identically to `FROM_SELF_CONTRACT`
26
- * since the emitting contract is also the self contract.
21
+ * For orchestrators, uses the service contract's domain.
22
+ * For handlers, behaves the same as FROM_SELF_CONTRACT.
27
23
  */
28
24
  FROM_EVENT_CONTRACT: 'domain.contract.inherit',
29
25
  /**
30
- * Resolve the domain from the triggering events `domain` field (`triggeringEvent.domain`).
26
+ * Resolve domain from the triggering event's domain field.
31
27
  *
32
- * Use this when you want to preserve the domain context of the incoming event
33
- * and carry it forward through event emissions.
28
+ * Preserves the domain context of the incoming event.
34
29
  */
35
30
  FROM_TRIGGERING_EVENT: 'domain.event.inherit',
36
31
  /**
37
- * Keep the event in the current execution context (null domain).
32
+ * Extract domain from the current event's subject.
33
+ *
34
+ * Parses the subject to retrieve `execution.domain`.
35
+ * Falls back to LOCAL if subject is not a valid ArvoOrchestrationSubject.
36
+ */
37
+ FROM_CURRENT_SUBJECT: 'domain.event.current.subject',
38
+ /**
39
+ * Extract domain from the parent orchestration subject.
38
40
  *
39
- * Use this when the event should remain local to the current domain without
40
- * crossing execution boundaries through the exchange layer.
41
+ * Parses the parent subject to retrieve `execution.domain`.
42
+ * Falls back to LOCAL if subject is not a valid ArvoOrchestrationSubject.
41
43
  */
42
- LOCAL: null
44
+ FROM_PARENT_SUBJECT: 'domain.parent.subject',
45
+ /**
46
+ * Resolve domain based on orchestration context.
47
+ *
48
+ * Routes responses and completions back through the orchestration chain:
49
+ * - For handlers: routes back to the orchestration's domain
50
+ * - For child orchestrations: routes to parent's domain if different, LOCAL if same
51
+ * - For root orchestrations: routes to own domain if cross-domain call, LOCAL otherwise
52
+ *
53
+ * This is the recommended default for maintaining domain coherence in orchestration workflows.
54
+ */
55
+ ORCHESTRATION_CONTEXT: 'domain.orchestration.context',
56
+ /**
57
+ * Stay in the current execution context (null domain).
58
+ *
59
+ * Event remains local without crossing domain boundaries.
60
+ */
61
+ LOCAL: null,
43
62
  };
44
63
  /**
45
- * Resolves a symbolic or static domain value into a concrete domain string or `null`.
64
+ * Extracts the domain from an ArvoOrchestrationSubject string.
46
65
  *
47
- * Used internally in the Arvo execution model to interpret symbolic domain constants
48
- * at the moment an event is emitted. Supports resolution from:
49
- * - the emitting handler's own contract
50
- * - the emitted event’s associated contract
51
- * - the triggering event’s `domain` field
66
+ * @param subject - Orchestration subject string or null
67
+ * @returns Domain from subject's execution context, or null if parsing fails
68
+ */
69
+ var getDomainFromArvoSubject = function (subject) {
70
+ if (subject === null)
71
+ return null;
72
+ try {
73
+ var parsedSubject = arvo_core_1.ArvoOrchestrationSubject.parse(subject);
74
+ return parsedSubject.execution.domain;
75
+ }
76
+ catch (e) {
77
+ (0, arvo_core_1.exceptionToSpan)(new Error("Unable to parse the provided subject. Falling back to ArvoDomain.LOCAL. Error: ".concat(e.message)));
78
+ }
79
+ return null;
80
+ };
81
+ /**
82
+ * Resolves symbolic domain constants to concrete domain values.
52
83
  *
53
- * @param param - Parameters for resolving the domain.
54
- * @param param.domainToResolve - Either a static domain string, symbolic value, or null.
55
- * @param param.handlerSelfContract - The contract of the handler currently emitting the event.
56
- * @param param.eventContract - The contract of the event being emitted (optional).
57
- * @param param.triggeringEvent - The triggering event that caused this emission.
84
+ * Interprets domain resolution symbols and returns the appropriate domain string or null.
85
+ * Static domain strings pass through unchanged.
58
86
  *
59
- * @returns A resolved domain string, or `null` if no valid domain is found.
87
+ * @param param.domainToResolve - Domain string or symbolic constant to resolve
88
+ * @param param.parentSubject - Parent orchestration subject (null for root orchestrations or handlers)
89
+ * @param param.currentSubject - Current event subject
90
+ * @param param.handlerSelfContract - Contract of the handler emitting the event
91
+ * @param param.eventContract - Contract of the event being emitted (optional)
92
+ * @param param.triggeringEvent - Event that triggered this emission
93
+ *
94
+ * @returns Resolved domain string or null
60
95
  */
61
96
  var resolveEventDomain = function (param) {
62
97
  var _a, _b;
63
- var ArvoDomainValues = Object.values(exports.ArvoDomain);
64
- if (param.domainToResolve && ArvoDomainValues.includes(param.domainToResolve)) {
65
- var domainToResolve = param.domainToResolve;
66
- if (domainToResolve === exports.ArvoDomain.FROM_EVENT_CONTRACT) {
67
- return (_b = (_a = param.eventContract) === null || _a === void 0 ? void 0 : _a.domain) !== null && _b !== void 0 ? _b : null;
68
- }
69
- if (domainToResolve === exports.ArvoDomain.FROM_SELF_CONTRACT) {
70
- return param.handlerSelfContract.domain;
98
+ if (!param.domainToResolve) {
99
+ return null;
100
+ }
101
+ if (param.domainToResolve === exports.ArvoDomain.LOCAL) {
102
+ return null;
103
+ }
104
+ if (param.domainToResolve === exports.ArvoDomain.FROM_EVENT_CONTRACT) {
105
+ return (_b = (_a = param.eventContract) === null || _a === void 0 ? void 0 : _a.domain) !== null && _b !== void 0 ? _b : null;
106
+ }
107
+ if (param.domainToResolve === exports.ArvoDomain.FROM_SELF_CONTRACT) {
108
+ return param.handlerSelfContract.domain;
109
+ }
110
+ if (param.domainToResolve === exports.ArvoDomain.FROM_TRIGGERING_EVENT) {
111
+ return param.triggeringEvent.domain;
112
+ }
113
+ if (param.domainToResolve === exports.ArvoDomain.FROM_CURRENT_SUBJECT) {
114
+ return getDomainFromArvoSubject(param.currentSubject);
115
+ }
116
+ if (param.domainToResolve === exports.ArvoDomain.FROM_PARENT_SUBJECT) {
117
+ return getDomainFromArvoSubject(param.parentSubject);
118
+ }
119
+ if (param.domainToResolve === exports.ArvoDomain.ORCHESTRATION_CONTEXT) {
120
+ var currentDomain = getDomainFromArvoSubject(param.currentSubject);
121
+ var parentDomain = getDomainFromArvoSubject(param.parentSubject);
122
+ var triggeringDomain = param.triggeringEvent.domain;
123
+ // No parent orchestration (root orchestration or handler)
124
+ if (param.parentSubject === null) {
125
+ // Triggering event is local
126
+ if (triggeringDomain === null) {
127
+ return null;
128
+ }
129
+ // Current and triggering domains match
130
+ if (currentDomain === triggeringDomain) {
131
+ return null;
132
+ }
133
+ // Cross-domain call - route back to orchestration's domain
134
+ return currentDomain;
71
135
  }
72
- if (domainToResolve === exports.ArvoDomain.FROM_TRIGGERING_EVENT) {
73
- return param.triggeringEvent.domain;
136
+ // Has parent orchestration
137
+ // Child and parent in same domain
138
+ if (currentDomain === parentDomain) {
139
+ return null;
74
140
  }
141
+ // Child in different domain - route to parent's domain
142
+ return parentDomain;
75
143
  }
144
+ // Static domain string
76
145
  return param.domainToResolve;
77
146
  };
78
147
  exports.resolveEventDomain = resolveEventDomain;
@@ -17,8 +17,8 @@ export default class ArvoEventHandler<TContract extends ArvoContract> implements
17
17
  readonly handler: ArvoEventHandlerFunction<TContract>;
18
18
  /** The source identifier for events produced by this handler */
19
19
  get source(): TContract['type'];
20
- /** Optional domains for routing system error events */
21
- readonly systemErrorDomain?: (string | null)[];
20
+ /** Domains for routing events */
21
+ readonly defaultEventEmissionDomains: Required<NonNullable<ArvoEventHandlerParam<TContract>['defaultEventEmissionDomains']>>;
22
22
  /** The contract-defined domain for the handler */
23
23
  get domain(): string | null;
24
24
  constructor(param: ArvoEventHandlerParam<TContract>);
@@ -40,21 +40,17 @@ export default class ArvoEventHandler<TContract extends ArvoContract> implements
40
40
  /**
41
41
  * Provides access to the system error event schema configuration.
42
42
  */
43
- get systemErrorSchema(): {
44
- domain: (string | null)[] | undefined;
45
- type: `sys.${string}.error`;
46
- schema: import("zod").ZodObject<{
47
- errorName: import("zod").ZodString;
48
- errorMessage: import("zod").ZodString;
49
- errorStack: import("zod").ZodNullable<import("zod").ZodString>;
50
- }, "strip", import("zod").ZodTypeAny, {
51
- errorName: string;
52
- errorMessage: string;
53
- errorStack: string | null;
54
- }, {
55
- errorName: string;
56
- errorMessage: string;
57
- errorStack: string | null;
58
- }>;
59
- };
43
+ get systemErrorSchema(): import("arvo-core").ArvoContractRecord<`sys.${string}.error`, import("zod").ZodObject<{
44
+ errorName: import("zod").ZodString;
45
+ errorMessage: import("zod").ZodString;
46
+ errorStack: import("zod").ZodNullable<import("zod").ZodString>;
47
+ }, "strip", import("zod").ZodTypeAny, {
48
+ errorName: string;
49
+ errorMessage: string;
50
+ errorStack: string | null;
51
+ }, {
52
+ errorName: string;
53
+ errorMessage: string;
54
+ errorStack: string | null;
55
+ }>>;
60
56
  }
@@ -72,20 +72,18 @@ var utils_1 = require("../utils");
72
72
  var ArvoEventHandler = /** @class */ (function () {
73
73
  function ArvoEventHandler(param) {
74
74
  var _a;
75
- var _b, _c;
76
- /** Optional domains for routing system error events */
77
- this.systemErrorDomain = undefined;
75
+ var _b, _c, _d;
78
76
  this.contract = param.contract;
79
77
  this.executionunits = param.executionunits;
80
78
  this.handler = param.handler;
81
- this.systemErrorDomain = param.systemErrorDomain;
82
- for (var _i = 0, _d = Object.keys(this.contract.versions); _i < _d.length; _i++) {
83
- var contractVersions = _d[_i];
79
+ this.defaultEventEmissionDomains = __assign({ systemError: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT], emits: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT] }, ((_b = param.defaultEventEmissionDomains) !== null && _b !== void 0 ? _b : {}));
80
+ for (var _i = 0, _e = Object.keys(this.contract.versions); _i < _e.length; _i++) {
81
+ var contractVersions = _e[_i];
84
82
  if (!this.handler[contractVersions]) {
85
83
  throw new Error("Contract ".concat(this.contract.uri, " requires handler implementation for version ").concat(contractVersions));
86
84
  }
87
85
  }
88
- this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.CONSUMER }, param.spanOptions), { attributes: __assign(__assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.EVENT_HANDLER, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), ((_c = (_b = param.spanOptions) === null || _b === void 0 ? void 0 : _b.attributes) !== null && _c !== void 0 ? _c : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': this.contract.uri }) });
86
+ this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.CONSUMER }, param.spanOptions), { attributes: __assign(__assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.EVENT_HANDLER, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), ((_d = (_c = param.spanOptions) === null || _c === void 0 ? void 0 : _c.attributes) !== null && _d !== void 0 ? _d : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': this.contract.uri }) });
89
87
  }
90
88
  Object.defineProperty(ArvoEventHandler.prototype, "source", {
91
89
  /** The source identifier for events produced by this handler */
@@ -127,14 +125,14 @@ var ArvoEventHandler = /** @class */ (function () {
127
125
  "Handler<".concat(this.contract.uri, ">"), this.spanOptions, opentelemetry !== null && opentelemetry !== void 0 ? opentelemetry : { inheritFrom: 'EVENT' }, event);
128
126
  return [4 /*yield*/, arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan(__assign(__assign({}, otelConfig), { fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
129
127
  var otelSpanHeaders, _i, _a, _b, key, value, parsedDataSchema, handlerContract_1, inputEventValidation, _handleOutput, outputs, result, _c, outputs_1, item, __extensions, handlerResult, domains, _d, _e, _dom, _f, _g, _h, key, value, error_1, errorEvents, _j, _k, _l, errEvtIdx, errEvt, _m, _o, _p, key, value;
130
- var _q, _r, _s, _t, _u, _v;
131
- return __generator(this, function (_w) {
132
- switch (_w.label) {
128
+ var _q, _r, _s, _t, _u;
129
+ return __generator(this, function (_v) {
130
+ switch (_v.label) {
133
131
  case 0:
134
132
  otelSpanHeaders = (0, arvo_core_1.currentOpenTelemetryHeaders)();
135
- _w.label = 1;
133
+ _v.label = 1;
136
134
  case 1:
137
- _w.trys.push([1, 3, 4, 5]);
135
+ _v.trys.push([1, 3, 4, 5]);
138
136
  span.setAttribute('arvo.handler.execution.status', 'normal');
139
137
  span.setAttribute('arvo.handler.execution.type', 'handler');
140
138
  span.setStatus({ code: api_1.SpanStatusCode.OK });
@@ -165,7 +163,7 @@ var ArvoEventHandler = /** @class */ (function () {
165
163
  try {
166
164
  handlerContract_1 = this.contract.version((_q = parsedDataSchema === null || parsedDataSchema === void 0 ? void 0 : parsedDataSchema.version) !== null && _q !== void 0 ? _q : 'latest');
167
165
  }
168
- catch (_x) {
166
+ catch (_w) {
169
167
  throw new errors_1.ConfigViolation("Invalid contract version: ".concat(parsedDataSchema === null || parsedDataSchema === void 0 ? void 0 : parsedDataSchema.version, ". Available versions: ").concat(Object.keys(this.contract.versions).join(', ')));
170
168
  }
171
169
  (0, arvo_core_1.logToSpan)({
@@ -196,7 +194,7 @@ var ArvoEventHandler = /** @class */ (function () {
196
194
  spanHeaders: otelSpanHeaders,
197
195
  })];
198
196
  case 2:
199
- _handleOutput = _w.sent();
197
+ _handleOutput = _v.sent();
200
198
  if (!_handleOutput)
201
199
  return [2 /*return*/, {
202
200
  events: [],
@@ -213,20 +211,22 @@ var ArvoEventHandler = /** @class */ (function () {
213
211
  item = outputs_1[_c];
214
212
  try {
215
213
  __extensions = item.__extensions, handlerResult = __rest(item, ["__extensions"]);
216
- domains = (_s = (_r = handlerResult.domain) === null || _r === void 0 ? void 0 : _r.map(function (item) {
214
+ domains = ((_r = handlerResult.domain) !== null && _r !== void 0 ? _r : this.defaultEventEmissionDomains.emits).map(function (item) {
217
215
  return (0, ArvoDomain_1.resolveEventDomain)({
216
+ parentSubject: null,
217
+ currentSubject: event.subject,
218
218
  domainToResolve: item,
219
219
  handlerSelfContract: handlerContract_1,
220
220
  eventContract: handlerContract_1,
221
221
  triggeringEvent: event,
222
222
  });
223
- })) !== null && _s !== void 0 ? _s : [event.domain];
223
+ });
224
224
  for (_d = 0, _e = Array.from(new Set(domains)); _d < _e.length; _d++) {
225
225
  _dom = _e[_d];
226
226
  result.push((0, arvo_core_1.createArvoEventFactory)(handlerContract_1).emits(__assign(__assign({}, handlerResult), { traceparent: otelSpanHeaders.traceparent || undefined, tracestate: otelSpanHeaders.tracestate || undefined, source: this.source, subject: event.subject,
227
227
  // 'source'
228
228
  // prioritise returned 'to', 'redirectto' and then
229
- to: (0, utils_1.coalesceOrDefault)([handlerResult.to, event.redirectto], event.source), executionunits: (0, utils_1.coalesce)(handlerResult.executionunits, this.executionunits), accesscontrol: (_u = (_t = handlerResult.accesscontrol) !== null && _t !== void 0 ? _t : event.accesscontrol) !== null && _u !== void 0 ? _u : undefined, parentid: event.id, domain: _dom }), __extensions));
229
+ to: (0, utils_1.coalesceOrDefault)([handlerResult.to, event.redirectto], event.source), executionunits: (0, utils_1.coalesce)(handlerResult.executionunits, this.executionunits), accesscontrol: (_t = (_s = handlerResult.accesscontrol) !== null && _s !== void 0 ? _s : event.accesscontrol) !== null && _t !== void 0 ? _t : undefined, parentid: event.id, domain: _dom }), __extensions));
230
230
  for (_f = 0, _g = Object.entries(result[result.length - 1].otelAttributes); _f < _g.length; _f++) {
231
231
  _h = _g[_f], key = _h[0], value = _h[1];
232
232
  span.setAttribute("emittables.".concat(result.length - 1, ".").concat(key), value);
@@ -234,12 +234,12 @@ var ArvoEventHandler = /** @class */ (function () {
234
234
  }
235
235
  }
236
236
  catch (e) {
237
- throw new errors_1.ContractViolation((_v = e === null || e === void 0 ? void 0 : e.message) !== null && _v !== void 0 ? _v : 'Invalid data');
237
+ throw new errors_1.ContractViolation((_u = e === null || e === void 0 ? void 0 : e.message) !== null && _u !== void 0 ? _u : 'Invalid data');
238
238
  }
239
239
  }
240
240
  return [2 /*return*/, (0, orchestrationExecutionWrapper_1.returnEventsWithLogging)({ events: result }, span)];
241
241
  case 3:
242
- error_1 = _w.sent();
242
+ error_1 = _v.sent();
243
243
  span.setAttribute('arvo.handler.execution.status', 'failure');
244
244
  (0, arvo_core_1.exceptionToSpan)(error_1);
245
245
  span.setStatus({
@@ -256,10 +256,9 @@ var ArvoEventHandler = /** @class */ (function () {
256
256
  orchestrationParentSubject: null,
257
257
  initEventId: event.id,
258
258
  selfContract: this.contract.version('any'),
259
- systemErrorDomain: this.systemErrorDomain,
259
+ systemErrorDomain: this.defaultEventEmissionDomains.systemError,
260
260
  executionunits: this.executionunits,
261
261
  source: this.source,
262
- domain: this.domain,
263
262
  handlerType: 'handler',
264
263
  });
265
264
  for (_j = 0, _k = Object.entries(errorEvents); _j < _k.length; _j++) {
@@ -289,7 +288,7 @@ var ArvoEventHandler = /** @class */ (function () {
289
288
  * Provides access to the system error event schema configuration.
290
289
  */
291
290
  get: function () {
292
- return __assign(__assign({}, this.contract.systemError), { domain: this.systemErrorDomain });
291
+ return this.contract.systemError;
293
292
  },
294
293
  enumerable: false,
295
294
  configurable: true
@@ -1,7 +1,7 @@
1
1
  import type { Span } from '@opentelemetry/api';
2
2
  import type { ArvoContract, ArvoEvent, ArvoSemanticVersion, CreateArvoEvent, InferArvoEvent, OpenTelemetryHeaders, VersionedArvoContract } from 'arvo-core';
3
3
  import type { z } from 'zod';
4
- import type { ArvoEventHandlerOtelSpanOptions } from '../types';
4
+ import type { ArvoEventHandlerOtelSpanOptions, NonEmptyArray } from '../types';
5
5
  /**
6
6
  * Represents the input for an ArvoEvent handler function.
7
7
  */
@@ -38,29 +38,18 @@ export type ArvoEventHandlerFunctionOutput<TContract extends VersionedArvoContra
38
38
  /** Optional extensions for the event. */
39
39
  __extensions?: Record<string, string | number | boolean>;
40
40
  /**
41
- * The domain configuration for multi-domain event broadcasting.
41
+ * Specifies which execution contexts should receive this event. Each domain value creates a separate routed event.
42
+ * Defaults to the domain encoded in the triggering event's subject with fallback to ArvoDomain.LOCAL (null) to
43
+ * maintain execution context continuity.
42
44
  *
43
- * When an event is emitted with a `domain` array, Arvo generates a separate ArvoEvent
44
- * for each resolved domain value. This enables parallel routing to multiple contexts
45
- * such as analytics, auditing, human-in-the-loop systems, or external integrations.
46
- *
47
- * **Accepted Values:**
48
- * - A concrete domain string (e.g. `'audit.orders'`)
49
- * - `null` for standard internal routing (no domain)
50
- * - A symbolic value from {@link ArvoDomain}.
51
- *
52
- * **Broadcasting Rules:**
53
- * - Each resolved domain in the array creates a separate ArvoEvent instance
54
- * - Duplicate resolved domains are automatically removed
55
- * - If the field is omitted, Arvo defaults to `[null]`
45
+ * @default [ArvoDomain.FROM_PARENT_SUBJECT]
56
46
  *
57
47
  * **Examples:**
58
- * - `['analytics.orders', 'audit.orders']` → Creates two routed events
59
- * - `[ArvoDomain.FROM_TRIGGERING_EVENT, 'human.review', null]` → Mirrors source domain, routes to review, and standard consumer
60
- * - `[null]` → Emits a single event with no domain routing
61
- * - _Omitted_ → Same as `[null]`
48
+ * - `['human.interaction', 'audit.reporting']` → Creates two routed events
49
+ * - `[ArvoDomain.FROM_TRIGGERING_EVENT, 'human.review']` → Mirrors source domain and routes to review
50
+ * - `[ArvoDomain.LOCAL]` → Stays in current execution context
62
51
  */
63
- domain?: (string | null)[];
52
+ domain?: NonEmptyArray<string | null>;
64
53
  };
65
54
  }[keyof TContract['emits']];
66
55
  /**
@@ -93,17 +82,28 @@ export type ArvoEventHandlerParam<TContract extends ArvoContract> = {
93
82
  */
94
83
  spanOptions?: ArvoEventHandlerOtelSpanOptions;
95
84
  /**
96
- * Optional configuration to customize where system error events are emitted.
97
- *
98
- * This overrides the default system error domain fallback of:
99
- * `[event.domain, handler.contract.domain, null]`
100
- *
101
- * Use this to precisely control the set of domains that should receive structured
102
- * `sys.*.error` events when uncaught exceptions occur in the handler.
103
- *
104
- * Symbolic constants from {@link ArvoDomain} are supported.
105
- *
106
- * @default undefined — uses standard fallback broadcast domains
85
+ * Optional default domains for the events emitted
86
+ * by the event handler.
107
87
  */
108
- systemErrorDomain?: (string | null)[];
88
+ defaultEventEmissionDomains?: {
89
+ /**
90
+ * Default domains for system error events emitted by this handler.
91
+ *
92
+ * System errors are routed through these domains when the handler encounters
93
+ * unhandled exceptions or critical failures.
94
+ *
95
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
96
+ */
97
+ systemError?: NonEmptyArray<string | null>;
98
+ /**
99
+ * Default domains for response events emitted by this handler.
100
+ *
101
+ * Response events are routed through these domains when the handler successfully
102
+ * processes an incoming event. Individual handler implementations can override
103
+ * this default on a per-event basis.
104
+ *
105
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
106
+ */
107
+ emits?: NonEmptyArray<string | null>;
108
+ };
109
109
  };
@@ -3,6 +3,7 @@ import { type ActionFunction, type MachineConfig, type MachineContext, type Meta
3
3
  import type { z } from 'zod';
4
4
  import ArvoMachine from '.';
5
5
  import type { EnqueueArvoEventActionParam, ExtractOrchestratorType, InferServiceContract, ToParameterizedObject, ToProvidedActor } from './types';
6
+ import { NonEmptyArray } from '../types';
6
7
  /**
7
8
  * Establishes the foundation for creating Arvo-compatible state machines.
8
9
  *
@@ -133,6 +134,7 @@ export declare function setupArvoMachine<TContext extends MachineContext, TSelfC
133
134
  }>, ToParameterizedObject<TGuards>, never, TTag, InferVersionedArvoContract<TSelfContract>["accepts"], z.input<TSelfContract["emits"][ReturnType<typeof ArvoOrchestratorEventTypeGen.complete<ExtractOrchestratorType<TSelfContract["accepts"]["type"]>>>]> & {
134
135
  __id?: CreateArvoEvent<Record<string, unknown>, string>["id"];
135
136
  __executionunits?: CreateArvoEvent<Record<string, unknown>, string>["executionunits"];
137
+ __domain?: NonEmptyArray<string | null>;
136
138
  }, InferServiceContract<TServiceContracts>["emitted"], TMeta>>(config: TConfig & {
137
139
  id: string;
138
140
  version?: TSelfContract["version"];
@@ -1,6 +1,7 @@
1
1
  import type { ArvoContract, ArvoEventData, ArvoOrchestratorEventTypeGen, ArvoSemanticVersion, CloudEventExtension, CreateArvoEvent, InferVersionedArvoContract, VersionedArvoContract } from 'arvo-core';
2
2
  import type { Invert, IsNever, ParameterizedObject, UnknownActorLogic, Values } from 'xstate';
3
3
  import type { z } from 'zod';
4
+ import { NonEmptyArray } from '../types';
4
5
  /**
5
6
  * Represents an extended context for Arvo XState machines, including additional properties
6
7
  * for volatile and internal data.
@@ -34,7 +35,7 @@ export type EnqueueArvoEventActionParam<TData extends ArvoEventData = ArvoEventD
34
35
  /**
35
36
  * The domain configuration for multi-domain event broadcasting.
36
37
  */
37
- domain?: (string | null)[];
38
+ domain?: NonEmptyArray<string | null>;
38
39
  /**
39
40
  * Custom extensions for the CloudEvent.
40
41
  * Allows for additional metadata to be attached to the event.
@@ -39,6 +39,8 @@ var createEmittableEvent = function (_a, span) {
39
39
  var parentId = sourceEvent.id;
40
40
  var domain = (0, ArvoDomain_1.resolveEventDomain)({
41
41
  domainToResolve: _domain,
42
+ parentSubject: orchestrationParentSubject,
43
+ currentSubject: sourceEvent.subject,
42
44
  handlerSelfContract: selfContract,
43
45
  eventContract: null,
44
46
  triggeringEvent: sourceEvent,
@@ -54,6 +56,8 @@ var createEmittableEvent = function (_a, span) {
54
56
  parentId = initEventId;
55
57
  domain = (0, ArvoDomain_1.resolveEventDomain)({
56
58
  domainToResolve: _domain,
59
+ parentSubject: orchestrationParentSubject,
60
+ currentSubject: sourceEvent.subject,
57
61
  handlerSelfContract: selfContract,
58
62
  eventContract: selfContract,
59
63
  triggeringEvent: sourceEvent,
@@ -68,6 +72,8 @@ var createEmittableEvent = function (_a, span) {
68
72
  schema = serviceContractMap[event.type].accepts.schema;
69
73
  domain = (0, ArvoDomain_1.resolveEventDomain)({
70
74
  domainToResolve: _domain,
75
+ parentSubject: orchestrationParentSubject,
76
+ currentSubject: sourceEvent.subject,
71
77
  handlerSelfContract: selfContract,
72
78
  eventContract: contract,
73
79
  triggeringEvent: sourceEvent,
@@ -3,6 +3,7 @@ import { type ArvoContract, type ArvoEvent, type ArvoSemanticVersion, type OpenT
3
3
  import type { SyncEventResource } from '../SyncEventResource';
4
4
  import type { OrchestrationExecutionMemoryRecord } from './orchestrationExecutionState';
5
5
  import { type ArvoOrchestrationHandlerType } from './types';
6
+ import type { NonEmptyArray } from '../types';
6
7
  /**
7
8
  * Parameters for creating system error events during orchestration failures.
8
9
  */
@@ -20,13 +21,11 @@ export type CreateSystemErrorEventsParams = {
20
21
  /** Self contract defining error schema */
21
22
  selfContract: VersionedArvoContract<ArvoContract, ArvoSemanticVersion>;
22
23
  /** Optional domains for error event routing */
23
- systemErrorDomain?: (string | null)[];
24
+ systemErrorDomain: NonEmptyArray<string | null>;
24
25
  /** Execution units for error events */
25
26
  executionunits: number;
26
27
  /** Source identifier */
27
28
  source: string;
28
- /** Domain for error events */
29
- domain: string | null;
30
29
  /** Type of handler reporting the error */
31
30
  handlerType: ArvoOrchestrationHandlerType;
32
31
  };
@@ -40,7 +39,7 @@ export type CreateSystemErrorEventsParams = {
40
39
  * @param params - Error event creation parameters
41
40
  * @returns Array of system error events for each configured domain
42
41
  */
43
- export declare const createSystemErrorEvents: ({ error, event, otelHeaders, orchestrationParentSubject: _orchestrationParentSubject, initEventId, selfContract, systemErrorDomain, executionunits, source, domain, handlerType, }: CreateSystemErrorEventsParams & {
42
+ export declare const createSystemErrorEvents: ({ error, event, otelHeaders, orchestrationParentSubject: _orchestrationParentSubject, initEventId, selfContract, systemErrorDomain, executionunits, source, handlerType, }: CreateSystemErrorEventsParams & {
44
43
  error: Error;
45
44
  }) => ArvoEvent[];
46
45
  /**
@@ -66,7 +66,7 @@ var types_1 = require("./types");
66
66
  */
67
67
  var createSystemErrorEvents = function (_a) {
68
68
  var _b, _c, _d, _e, _f;
69
- var error = _a.error, event = _a.event, otelHeaders = _a.otelHeaders, _orchestrationParentSubject = _a.orchestrationParentSubject, initEventId = _a.initEventId, selfContract = _a.selfContract, systemErrorDomain = _a.systemErrorDomain, executionunits = _a.executionunits, source = _a.source, domain = _a.domain, handlerType = _a.handlerType;
69
+ var error = _a.error, event = _a.event, otelHeaders = _a.otelHeaders, _orchestrationParentSubject = _a.orchestrationParentSubject, initEventId = _a.initEventId, selfContract = _a.selfContract, systemErrorDomain = _a.systemErrorDomain, executionunits = _a.executionunits, source = _a.source, handlerType = _a.handlerType;
70
70
  // In case of none transaction errors like errors from
71
71
  // the machine or the event creation etc, the are workflow
72
72
  // error and shuold be handled by the workflow. Then are
@@ -86,18 +86,18 @@ var createSystemErrorEvents = function (_a) {
86
86
  });
87
87
  }
88
88
  }
89
- var domainSets = new Set((systemErrorDomain === null || systemErrorDomain === void 0 ? void 0 : systemErrorDomain.length)
90
- ? systemErrorDomain.map(function (item) {
91
- return (0, ArvoDomain_1.resolveEventDomain)({
92
- domainToResolve: item,
93
- handlerSelfContract: selfContract,
94
- eventContract: selfContract,
95
- triggeringEvent: event,
96
- });
97
- })
98
- : [event.domain, domain, null]);
89
+ var domainSets = systemErrorDomain.map(function (item) {
90
+ return (0, ArvoDomain_1.resolveEventDomain)({
91
+ parentSubject: orchestrationParentSubject,
92
+ currentSubject: event.subject,
93
+ domainToResolve: item,
94
+ handlerSelfContract: selfContract,
95
+ eventContract: selfContract,
96
+ triggeringEvent: event,
97
+ });
98
+ });
99
99
  var result = [];
100
- for (var _i = 0, _g = Array.from(domainSets); _i < _g.length; _i++) {
100
+ for (var _i = 0, _g = Array.from(new Set(domainSets)); _i < _g.length; _i++) {
101
101
  var _dom = _g[_i];
102
102
  var factoryBuilder = handlerType === 'handler' ? arvo_core_1.createArvoEventFactory : arvo_core_1.createArvoOrchestratorEventFactory;
103
103
  result.push(factoryBuilder(selfContract).systemError({
@@ -2,7 +2,7 @@ import { type Span } from '@opentelemetry/api';
2
2
  import { type ArvoEvent, type ArvoOrchestrationSubjectContent, type ArvoOrchestratorContract, type ArvoSemanticVersion, type OpenTelemetryHeaders, type VersionedArvoContract } from 'arvo-core';
3
3
  import type IArvoEventHandler from '../../IArvoEventHandler';
4
4
  import type { SyncEventResource } from '../../SyncEventResource';
5
- import type { ArvoEventHandlerOpenTelemetryOptions, ArvoEventHandlerOtelSpanOptions } from '../../types';
5
+ import type { ArvoEventHandlerOpenTelemetryOptions, ArvoEventHandlerOtelSpanOptions, NonEmptyArray } from '../../types';
6
6
  import type { OrchestrationExecutionMemoryRecord } from '../orchestrationExecutionState';
7
7
  import type { ArvoOrchestrationHandlerType } from '../types';
8
8
  /**
@@ -21,11 +21,9 @@ export type OrchestrationExecutionContext<TState extends OrchestrationExecutionM
21
21
  /** Maximum execution units per cycle */
22
22
  executionunits: number;
23
23
  /** Optional domains for system error routing */
24
- systemErrorDomain?: (string | null)[];
24
+ systemErrorDomain: NonEmptyArray<string | null>;
25
25
  /** Self contract defining orchestrator interface */
26
26
  selfContract: VersionedArvoContract<ArvoOrchestratorContract, ArvoSemanticVersion>;
27
- /** Domain for event routing */
28
- domain: string | null;
29
27
  /** Type of orchestration handler */
30
28
  _handlerType: ArvoOrchestrationHandlerType;
31
29
  /** OpenTelemetry span configuration */
@@ -78,4 +76,4 @@ export declare const returnEventsWithLogging: (param: Awaited<ReturnType<IArvoEv
78
76
  * while allowing custom core logic via the execution function parameter.
79
77
  * @returns Emitted events from successful execution or error handling
80
78
  */
81
- export declare const executeWithOrchestrationWrapper: <TState extends OrchestrationExecutionMemoryRecord<Record<string, any>>>({ event, opentelemetry, spanOptions, source, syncEventResource, executionunits, systemErrorDomain, selfContract, domain, _handlerType, }: OrchestrationExecutionContext<TState>, coreExecutionFn: CoreExecutionFn<TState>) => Promise<Awaited<ReturnType<IArvoEventHandler["execute"]>>>;
79
+ export declare const executeWithOrchestrationWrapper: <TState extends OrchestrationExecutionMemoryRecord<Record<string, any>>>({ event, opentelemetry, spanOptions, source, syncEventResource, executionunits, systemErrorDomain, selfContract, _handlerType, }: OrchestrationExecutionContext<TState>, coreExecutionFn: CoreExecutionFn<TState>) => Promise<Awaited<ReturnType<IArvoEventHandler["execute"]>>>;
@@ -84,7 +84,7 @@ exports.returnEventsWithLogging = returnEventsWithLogging;
84
84
  */
85
85
  var executeWithOrchestrationWrapper = function (_a, coreExecutionFn_1) { return __awaiter(void 0, [_a, coreExecutionFn_1], void 0, function (_b, coreExecutionFn) {
86
86
  var otelConfig;
87
- var event = _b.event, opentelemetry = _b.opentelemetry, spanOptions = _b.spanOptions, source = _b.source, syncEventResource = _b.syncEventResource, executionunits = _b.executionunits, systemErrorDomain = _b.systemErrorDomain, selfContract = _b.selfContract, domain = _b.domain, _handlerType = _b._handlerType;
87
+ var event = _b.event, opentelemetry = _b.opentelemetry, spanOptions = _b.spanOptions, source = _b.source, syncEventResource = _b.syncEventResource, executionunits = _b.executionunits, systemErrorDomain = _b.systemErrorDomain, selfContract = _b.selfContract, _handlerType = _b._handlerType;
88
88
  return __generator(this, function (_c) {
89
89
  switch (_c.label) {
90
90
  case 0:
@@ -206,7 +206,6 @@ var executeWithOrchestrationWrapper = function (_a, coreExecutionFn_1) { return
206
206
  systemErrorDomain: systemErrorDomain,
207
207
  executionunits: executionunits,
208
208
  source: source,
209
- domain: domain,
210
209
  syncEventResource: syncEventResource,
211
210
  handlerType: _handlerType,
212
211
  }, span)];
@@ -29,4 +29,4 @@ import type { CreateArvoOrchestratorParam } from './types';
29
29
  * @see {@link setupArvoMachine} for creating machine definitions
30
30
  * @see {@link ArvoOrchestrator} for direct instantiation with custom components
31
31
  */
32
- export declare const createArvoOrchestrator: ({ executionunits, memory, machines, systemErrorDomain, spanOptions, requiresResourceLocking: _locking, }: CreateArvoOrchestratorParam) => ArvoOrchestrator;
32
+ export declare const createArvoOrchestrator: ({ executionunits, memory, machines, defaultEventEmissionDomains, spanOptions, requiresResourceLocking: _locking, }: CreateArvoOrchestratorParam) => ArvoOrchestrator;
@@ -44,7 +44,7 @@ var errors_1 = require("../errors");
44
44
  * @see {@link ArvoOrchestrator} for direct instantiation with custom components
45
45
  */
46
46
  var createArvoOrchestrator = function (_a) {
47
- var executionunits = _a.executionunits, memory = _a.memory, machines = _a.machines, systemErrorDomain = _a.systemErrorDomain, spanOptions = _a.spanOptions, _locking = _a.requiresResourceLocking;
47
+ var executionunits = _a.executionunits, memory = _a.memory, machines = _a.machines, defaultEventEmissionDomains = _a.defaultEventEmissionDomains, spanOptions = _a.spanOptions, _locking = _a.requiresResourceLocking;
48
48
  if (!(machines === null || machines === void 0 ? void 0 : machines.length)) {
49
49
  throw new Error('At least one machine must be provided');
50
50
  }
@@ -68,7 +68,7 @@ var createArvoOrchestrator = function (_a) {
68
68
  registry: registry,
69
69
  executionEngine: new MachineExecutionEngine_1.MachineExecutionEngine(),
70
70
  requiresResourceLocking: requiresResourceLocking,
71
- systemErrorDomain: systemErrorDomain,
71
+ defaultEventEmissionDomains: defaultEventEmissionDomains,
72
72
  spanOptions: spanOptions,
73
73
  });
74
74
  };
@@ -22,8 +22,8 @@ export declare class ArvoOrchestrator implements IArvoEventHandler {
22
22
  readonly executionEngine: IMachineExectionEngine;
23
23
  /** Resource manager for state synchronization and memory access */
24
24
  readonly syncEventResource: SyncEventResource<MachineMemoryRecord>;
25
- /** Optional domains for routing system error events */
26
- readonly systemErrorDomain?: (string | null)[];
25
+ /** Domains for routing events */
26
+ readonly defaultEventEmissionDomains: Required<NonNullable<ArvoOrchestratorParam['defaultEventEmissionDomains']>>;
27
27
  /** OpenTelemetry span configuration for observability */
28
28
  readonly spanOptions: ArvoEventHandlerOtelSpanOptions;
29
29
  /** Source identifier from the first registered machine */
@@ -34,7 +34,7 @@ export declare class ArvoOrchestrator implements IArvoEventHandler {
34
34
  get memory(): IMachineMemory<MachineMemoryRecord>;
35
35
  /** The contract-defined domain for the handler */
36
36
  get domain(): string | null;
37
- constructor({ executionunits, memory, registry, executionEngine, requiresResourceLocking, systemErrorDomain, spanOptions, }: ArvoOrchestratorParam);
37
+ constructor({ executionunits, memory, registry, executionEngine, requiresResourceLocking, defaultEventEmissionDomains, spanOptions, }: ArvoOrchestratorParam);
38
38
  /**
39
39
  * Executes state machine orchestration for an incoming event.
40
40
  *
@@ -76,6 +76,5 @@ export declare class ArvoOrchestrator implements IArvoEventHandler {
76
76
  errorMessage: string;
77
77
  errorStack: string | null;
78
78
  }>;
79
- domain: (string | null)[] | undefined;
80
79
  };
81
80
  }
@@ -65,15 +65,13 @@ var ArvoDomain_1 = require("../ArvoDomain");
65
65
  var ArvoOrchestrator = /** @class */ (function () {
66
66
  function ArvoOrchestrator(_a) {
67
67
  var _b;
68
- var executionunits = _a.executionunits, memory = _a.memory, registry = _a.registry, executionEngine = _a.executionEngine, requiresResourceLocking = _a.requiresResourceLocking, systemErrorDomain = _a.systemErrorDomain, spanOptions = _a.spanOptions;
68
+ var executionunits = _a.executionunits, memory = _a.memory, registry = _a.registry, executionEngine = _a.executionEngine, requiresResourceLocking = _a.requiresResourceLocking, defaultEventEmissionDomains = _a.defaultEventEmissionDomains, spanOptions = _a.spanOptions;
69
69
  var _c, _d, _e, _f, _g, _h, _j;
70
- /** Optional domains for routing system error events */
71
- this.systemErrorDomain = undefined;
72
70
  this.executionunits = executionunits;
73
71
  this.registry = registry;
74
72
  this.executionEngine = executionEngine;
75
73
  this.syncEventResource = new SyncEventResource_1.SyncEventResource(memory, requiresResourceLocking);
76
- this.systemErrorDomain = systemErrorDomain;
74
+ this.defaultEventEmissionDomains = __assign({ systemError: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT], services: [ArvoDomain_1.ArvoDomain.LOCAL], complete: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT] }, (defaultEventEmissionDomains !== null && defaultEventEmissionDomains !== void 0 ? defaultEventEmissionDomains : {}));
77
75
  this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.PRODUCER }, spanOptions), { attributes: __assign(__assign((_b = {}, _b[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.ORCHESTRATOR, _b[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _b), ((_c = spanOptions === null || spanOptions === void 0 ? void 0 : spanOptions.attributes) !== null && _c !== void 0 ? _c : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': (_j = (_h = (_g = (_f = (_e = (_d = this === null || this === void 0 ? void 0 : this.registry) === null || _d === void 0 ? void 0 : _d.machines) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.contracts) === null || _g === void 0 ? void 0 : _g.self) === null || _h === void 0 ? void 0 : _h.uri) !== null && _j !== void 0 ? _j : 'N/A' }) });
78
76
  }
79
77
  Object.defineProperty(ArvoOrchestrator.prototype, "source", {
@@ -144,14 +142,13 @@ var ArvoOrchestrator = /** @class */ (function () {
144
142
  source: this.source,
145
143
  syncEventResource: this.syncEventResource,
146
144
  executionunits: this.executionunits,
147
- systemErrorDomain: this.systemErrorDomain,
145
+ systemErrorDomain: this.defaultEventEmissionDomains.systemError,
148
146
  selfContract: this.registry.machines[0].contracts.self,
149
- domain: this.domain,
150
147
  }, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
151
- var machine, inputValidation, executionResult, rawMachineEmittedEvents, emittables, newState;
152
- var _c, _d, _e, _f;
148
+ var machine, inputValidation, executionResult, rawMachineEmittedEvents, i, emittables, newState;
149
+ var _c, _d, _e, _f, _g, _h;
153
150
  var span = _b.span, otelHeaders = _b.otelHeaders, orchestrationParentSubject = _b.orchestrationParentSubject, initEventId = _b.initEventId, parsedEventSubject = _b.parsedEventSubject, state = _b.state;
154
- return __generator(this, function (_g) {
151
+ return __generator(this, function (_j) {
155
152
  (0, arvo_core_1.logToSpan)({
156
153
  level: 'INFO',
157
154
  message: "Resolving machine for event ".concat(event.type),
@@ -174,15 +171,22 @@ var ArvoOrchestrator = /** @class */ (function () {
174
171
  executionResult = this.executionEngine.execute({ state: (_c = state === null || state === void 0 ? void 0 : state.state) !== null && _c !== void 0 ? _c : null, event: event, machine: machine }, { inheritFrom: 'CONTEXT' });
175
172
  span.setAttribute('arvo.orchestration.status', executionResult.state.status);
176
173
  rawMachineEmittedEvents = executionResult.events;
174
+ // For all the service events (non final output) make sure
175
+ // that the default domain is this.defaultEventEmissionDomains.services.
176
+ // This is because the assumption is that all the normal services
177
+ // the orchestrator usually talks to are in the same local
178
+ // domain.
179
+ for (i = 0; i < rawMachineEmittedEvents.length; i++) {
180
+ rawMachineEmittedEvents[i].domain =
181
+ (_d = rawMachineEmittedEvents[i].domain) !== null && _d !== void 0 ? _d : this.defaultEventEmissionDomains.services;
182
+ }
177
183
  if (executionResult.finalOutput) {
178
184
  rawMachineEmittedEvents.push({
179
185
  type: machine.contracts.self.metadata.completeEventType,
180
186
  id: executionResult.finalOutput.__id,
181
187
  data: executionResult.finalOutput,
182
- to: (_e = (_d = parsedEventSubject.meta) === null || _d === void 0 ? void 0 : _d.redirectto) !== null && _e !== void 0 ? _e : parsedEventSubject.execution.initiator,
183
- domain: orchestrationParentSubject
184
- ? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
185
- : [ArvoDomain_1.ArvoDomain.LOCAL],
188
+ to: (_f = (_e = parsedEventSubject.meta) === null || _e === void 0 ? void 0 : _e.redirectto) !== null && _f !== void 0 ? _f : parsedEventSubject.execution.initiator,
189
+ domain: (_g = executionResult.finalOutput.__domain) !== null && _g !== void 0 ? _g : this.defaultEventEmissionDomains.complete,
186
190
  executionunits: executionResult.finalOutput.__executionunits,
187
191
  });
188
192
  }
@@ -207,7 +211,7 @@ var ArvoOrchestrator = /** @class */ (function () {
207
211
  subject: event.subject,
208
212
  parentSubject: orchestrationParentSubject,
209
213
  status: executionResult.state.status,
210
- value: (_f = executionResult.state.value) !== null && _f !== void 0 ? _f : null,
214
+ value: (_h = executionResult.state.value) !== null && _h !== void 0 ? _h : null,
211
215
  state: executionResult.state,
212
216
  events: {
213
217
  consumed: event.toJSON(),
@@ -231,7 +235,6 @@ var ArvoOrchestrator = /** @class */ (function () {
231
235
  return {
232
236
  type: this.registry.machines[0].contracts.self.systemError.type,
233
237
  schema: arvo_core_1.ArvoErrorSchema,
234
- domain: this.systemErrorDomain,
235
238
  };
236
239
  },
237
240
  enumerable: false,
@@ -5,7 +5,7 @@ import type { OrchestrationExecutionMemoryRecord } from '../ArvoOrchestrationUti
5
5
  import type { IMachineExectionEngine } from '../MachineExecutionEngine/interface';
6
6
  import type { IMachineMemory } from '../MachineMemory/interface';
7
7
  import type { IMachineRegistry } from '../MachineRegistry/interface';
8
- import type { ArvoEventHandlerOtelSpanOptions } from '../types';
8
+ import type { ArvoEventHandlerOtelSpanOptions, NonEmptyArray } from '../types';
9
9
  /**
10
10
  * Discriminated union representing the result of a try operation.
11
11
  */
@@ -93,20 +93,41 @@ export type ArvoOrchestratorParam = {
93
93
  executionEngine: IMachineExectionEngine;
94
94
  /** Whether to enforce resource locking for concurrent safety */
95
95
  requiresResourceLocking: boolean;
96
- /**
97
- * Optional domains for system error event routing.
98
- *
99
- * Overrides the default fallback sequence of:
100
- * `[event.domain, self.contract.domain, null]`
101
- *
102
- * Controls where structured `sys.*.error` events are emitted when
103
- * uncaught exceptions occur. Supports symbolic constants from {@link ArvoDomain}.
104
- *
105
- * @default undefined - uses standard fallback broadcast domains
106
- */
107
- systemErrorDomain?: (string | null)[];
108
96
  /** OpenTelemetry span configuration for distributed tracing */
109
97
  spanOptions?: ArvoEventHandlerOtelSpanOptions;
98
+ /**
99
+ * Optional default domains for the events emitted
100
+ * by the orchestrator.
101
+ */
102
+ defaultEventEmissionDomains?: {
103
+ /**
104
+ * Default domains for system error events emitted by this orchestrator.
105
+ *
106
+ * System errors are routed through these domains when the handler encounters
107
+ * unhandled exceptions or critical failures.
108
+ *
109
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
110
+ */
111
+ systemError?: NonEmptyArray<string | null>;
112
+ /**
113
+ * Default domains for service events emitted by this orchestrator.
114
+ *
115
+ * The service xstate.emit function can over-ride this default.
116
+ *
117
+ * @default [ArvoDomain.LOCAL]
118
+ */
119
+ services?: NonEmptyArray<string | null>;
120
+ /**
121
+ * Defauld domain for the final completion event emitted by this orchestrator
122
+ *
123
+ * Completion event is routed through these domains when the orchestrator successfully
124
+ * processes an init event. The machine 'output' transform function implementations can override
125
+ * this default.
126
+ *
127
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
128
+ */
129
+ complete?: NonEmptyArray<string | null>;
130
+ };
110
131
  };
111
132
  /**
112
133
  * Configuration parameters for creating an orchestrator via factory function.
@@ -114,7 +135,7 @@ export type ArvoOrchestratorParam = {
114
135
  * Simplified interface for {@link createArvoOrchestrator} that automatically
115
136
  * constructs default registry and execution engine components.
116
137
  */
117
- export type CreateArvoOrchestratorParam = Pick<ArvoOrchestratorParam, 'memory' | 'executionunits' | 'spanOptions' | 'systemErrorDomain'> & {
138
+ export type CreateArvoOrchestratorParam = Pick<ArvoOrchestratorParam, 'memory' | 'executionunits' | 'spanOptions' | 'defaultEventEmissionDomains'> & {
118
139
  /**
119
140
  * Optional override for resource locking requirement.
120
141
  *
@@ -47,7 +47,7 @@ var createArvoResumable = function (param) {
47
47
  handler: param.handler,
48
48
  executionunits: (_a = param.executionunits) !== null && _a !== void 0 ? _a : 0,
49
49
  requiresResourceLocking: (_b = param.requiresResourceLocking) !== null && _b !== void 0 ? _b : Object.keys(param.contracts.services).length > 1,
50
- systemErrorDomain: param.systemErrorDomain,
50
+ defaultEventEmissionDomains: param.defaultEventEmissionDomains,
51
51
  spanOptions: param.spanOptions,
52
52
  });
53
53
  };
@@ -23,8 +23,8 @@ export declare class ArvoResumable<TMemory extends Record<string, any> = Record<
23
23
  readonly syncEventResource: SyncEventResource<ArvoResumableState<TMemory>>;
24
24
  /** Versioned handler map for processing workflow events. */
25
25
  readonly handler: ArvoResumableHandler<ArvoResumableState<TMemory>, TSelfContract, TServiceContract>;
26
- /** Optional domains for routing system error events */
27
- readonly systemErrorDomain?: (string | null)[];
26
+ /** Optional domains for routing events */
27
+ readonly defaultEventEmissionDomains: Required<NonNullable<ArvoResumableParam<TMemory, TSelfContract, TServiceContract>['defaultEventEmissionDomains']>>;
28
28
  /** OpenTelemetry span configuration for observability */
29
29
  readonly spanOptions: ArvoEventHandlerOtelSpanOptions;
30
30
  /** Source identifier from the first registered machine */
@@ -82,21 +82,17 @@ export declare class ArvoResumable<TMemory extends Record<string, any> = Record<
82
82
  execute(event: ArvoEvent, opentelemetry?: ArvoEventHandlerOpenTelemetryOptions): Promise<{
83
83
  events: ArvoEvent[];
84
84
  }>;
85
- get systemErrorSchema(): {
86
- domain: (string | null)[] | undefined;
87
- type: `sys.arvo.orc.${string}.error`;
88
- schema: import("zod").ZodObject<{
89
- errorName: import("zod").ZodString;
90
- errorMessage: import("zod").ZodString;
91
- errorStack: import("zod").ZodNullable<import("zod").ZodString>;
92
- }, "strip", import("zod").ZodTypeAny, {
93
- errorName: string;
94
- errorMessage: string;
95
- errorStack: string | null;
96
- }, {
97
- errorName: string;
98
- errorMessage: string;
99
- errorStack: string | null;
100
- }>;
101
- };
85
+ get systemErrorSchema(): import("arvo-core").ArvoContractRecord<`sys.arvo.orc.${string}.error`, import("zod").ZodObject<{
86
+ errorName: import("zod").ZodString;
87
+ errorMessage: import("zod").ZodString;
88
+ errorStack: import("zod").ZodNullable<import("zod").ZodString>;
89
+ }, "strip", import("zod").ZodTypeAny, {
90
+ errorName: string;
91
+ errorMessage: string;
92
+ errorStack: string | null;
93
+ }, {
94
+ errorName: string;
95
+ errorMessage: string;
96
+ errorStack: string | null;
97
+ }>>;
102
98
  }
@@ -69,16 +69,14 @@ var ArvoDomain_1 = require("../ArvoDomain");
69
69
  var ArvoResumable = /** @class */ (function () {
70
70
  function ArvoResumable(param) {
71
71
  var _a;
72
- var _b, _c, _d;
73
- /** Optional domains for routing system error events */
74
- this.systemErrorDomain = undefined;
72
+ var _b, _c, _d, _e;
75
73
  this.executionunits = param.executionunits;
76
74
  this.source = param.contracts.self.type;
77
75
  this.syncEventResource = new index_1.SyncEventResource(param.memory, (_b = param.requiresResourceLocking) !== null && _b !== void 0 ? _b : true);
78
76
  this.contracts = param.contracts;
79
77
  this.handler = param.handler;
80
- this.systemErrorDomain = param.systemErrorDomain;
81
- this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.PRODUCER }, param.spanOptions), { attributes: __assign(__assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.RESUMABLE, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), ((_d = (_c = param.spanOptions) === null || _c === void 0 ? void 0 : _c.attributes) !== null && _d !== void 0 ? _d : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': this.contracts.self.uri }) });
78
+ this.defaultEventEmissionDomains = __assign({ systemError: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT], services: [ArvoDomain_1.ArvoDomain.LOCAL], complete: [ArvoDomain_1.ArvoDomain.ORCHESTRATION_CONTEXT] }, ((_c = param.defaultEventEmissionDomains) !== null && _c !== void 0 ? _c : {}));
79
+ this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.PRODUCER }, param.spanOptions), { attributes: __assign(__assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.RESUMABLE, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), ((_e = (_d = param.spanOptions) === null || _d === void 0 ? void 0 : _d.attributes) !== null && _e !== void 0 ? _e : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': this.contracts.self.uri }) });
82
80
  }
83
81
  Object.defineProperty(ArvoResumable.prototype, "requiresResourceLocking", {
84
82
  /** Whether this resumable requires resource locking for concurrent safety */
@@ -156,15 +154,14 @@ var ArvoResumable = /** @class */ (function () {
156
154
  source: this.source,
157
155
  syncEventResource: this.syncEventResource,
158
156
  executionunits: this.executionunits,
159
- systemErrorDomain: this.systemErrorDomain,
157
+ systemErrorDomain: this.defaultEventEmissionDomains.systemError,
160
158
  selfContract: this.contracts.self.version('latest'),
161
- domain: this.domain,
162
159
  }, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
163
- var inputValidation, contractType, eventTypeToExpectedEvent, _i, _c, _d, _, eventList, _e, eventList_1, _evt, handler, versionedSelfContract, executionResult, rawEvents, emittables, eventTrackingState, newState;
164
- var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
160
+ var inputValidation, contractType, eventTypeToExpectedEvent, _i, _c, _d, _, eventList, _e, eventList_1, _evt, handler, versionedSelfContract, executionResult, rawEvents, i, emittables, eventTrackingState, newState;
161
+ var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
165
162
  var span = _b.span, otelHeaders = _b.otelHeaders, orchestrationParentSubject = _b.orchestrationParentSubject, initEventId = _b.initEventId, parsedEventSubject = _b.parsedEventSubject, state = _b.state;
166
- return __generator(this, function (_v) {
167
- switch (_v.label) {
163
+ return __generator(this, function (_y) {
164
+ switch (_y.label) {
168
165
  case 0:
169
166
  (0, arvo_core_1.logToSpan)({
170
167
  level: 'INFO',
@@ -231,17 +228,18 @@ var ArvoResumable = /** @class */ (function () {
231
228
  },
232
229
  })];
233
230
  case 1:
234
- executionResult = _v.sent();
231
+ executionResult = _y.sent();
235
232
  rawEvents = (_o = executionResult === null || executionResult === void 0 ? void 0 : executionResult.services) !== null && _o !== void 0 ? _o : [];
233
+ for (i = 0; i < rawEvents.length; i++) {
234
+ rawEvents[i].domain = (_p = rawEvents[i].domain) !== null && _p !== void 0 ? _p : this.defaultEventEmissionDomains.services;
235
+ }
236
236
  if (executionResult === null || executionResult === void 0 ? void 0 : executionResult.output) {
237
237
  rawEvents.push({
238
238
  id: executionResult.output.__id,
239
239
  data: executionResult.output,
240
240
  type: this.contracts.self.metadata.completeEventType,
241
- to: (_q = (_p = parsedEventSubject.meta) === null || _p === void 0 ? void 0 : _p.redirectto) !== null && _q !== void 0 ? _q : parsedEventSubject.execution.initiator,
242
- domain: orchestrationParentSubject
243
- ? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
244
- : [ArvoDomain_1.ArvoDomain.LOCAL],
241
+ to: (_r = (_q = parsedEventSubject.meta) === null || _q === void 0 ? void 0 : _q.redirectto) !== null && _r !== void 0 ? _r : parsedEventSubject.execution.initiator,
242
+ domain: (_t = (_s = executionResult.output) === null || _s === void 0 ? void 0 : _s.__domain) !== null && _t !== void 0 ? _t : this.defaultEventEmissionDomains.complete,
245
243
  executionunits: executionResult.output.__executionunits,
246
244
  });
247
245
  }
@@ -264,7 +262,7 @@ var ArvoResumable = /** @class */ (function () {
264
262
  consumed: event.toJSON(),
265
263
  expected: emittables.length
266
264
  ? Object.fromEntries(emittables.map(function (item) { return [item.id, []]; }))
267
- : ((_s = (_r = state === null || state === void 0 ? void 0 : state.events) === null || _r === void 0 ? void 0 : _r.expected) !== null && _s !== void 0 ? _s : null),
265
+ : ((_v = (_u = state === null || state === void 0 ? void 0 : state.events) === null || _u === void 0 ? void 0 : _u.expected) !== null && _v !== void 0 ? _v : null),
268
266
  produced: emittables.map(function (item) { return item.toJSON(); }),
269
267
  };
270
268
  newState = {
@@ -274,7 +272,7 @@ var ArvoResumable = /** @class */ (function () {
274
272
  parentSubject: orchestrationParentSubject,
275
273
  subject: event.subject,
276
274
  events: eventTrackingState,
277
- state$$: (_u = (_t = executionResult === null || executionResult === void 0 ? void 0 : executionResult.context) !== null && _t !== void 0 ? _t : state === null || state === void 0 ? void 0 : state.state$$) !== null && _u !== void 0 ? _u : null,
275
+ state$$: (_x = (_w = executionResult === null || executionResult === void 0 ? void 0 : executionResult.context) !== null && _w !== void 0 ? _w : state === null || state === void 0 ? void 0 : state.state$$) !== null && _x !== void 0 ? _x : null,
278
276
  };
279
277
  return [2 /*return*/, { emittables: emittables, newState: newState }];
280
278
  }
@@ -287,7 +285,7 @@ var ArvoResumable = /** @class */ (function () {
287
285
  };
288
286
  Object.defineProperty(ArvoResumable.prototype, "systemErrorSchema", {
289
287
  get: function () {
290
- return __assign(__assign({}, this.contracts.self.systemError), { domain: this.systemErrorDomain });
288
+ return this.contracts.self.systemError;
291
289
  },
292
290
  enumerable: false,
293
291
  configurable: true
@@ -3,7 +3,7 @@ import type { ArvoContract, ArvoEvent, ArvoOrchestratorContract, ArvoSemanticVer
3
3
  import type { EnqueueArvoEventActionParam } from '../ArvoMachine/types';
4
4
  import type { OrchestrationExecutionMemoryRecord } from '../ArvoOrchestrationUtils/orchestrationExecutionState';
5
5
  import type { IMachineMemory } from '../MachineMemory/interface';
6
- import type { ArvoEventHandlerOtelSpanOptions } from '../types';
6
+ import type { ArvoEventHandlerOtelSpanOptions, NonEmptyArray } from '../types';
7
7
  /**
8
8
  * Extracts all possible event types (including system errors) from service contracts.
9
9
  */
@@ -98,6 +98,7 @@ type Handler<TState extends ArvoResumableState<Record<string, any>>, TSelfContra
98
98
  }[keyof InferVersionedArvoContract<TSelfContract>['emits']] & {
99
99
  __id?: CreateArvoEvent<Record<string, unknown>, string>['id'];
100
100
  __executionunits?: CreateArvoEvent<Record<string, unknown>, string>['executionunits'];
101
+ __domain?: NonEmptyArray<string | null>;
101
102
  };
102
103
  /**
103
104
  * Service call events to emit.
@@ -219,10 +220,47 @@ export type ArvoResumableParam<TMemory extends Record<string, any>, TSelfContrac
219
220
  * Each contract version maps to its corresponding handler implementation.
220
221
  */
221
222
  handler: ArvoResumableHandler<ArvoResumableState<TMemory>, TSelfContract, TServiceContract>;
222
- /** Optional domains for system error event routing */
223
- systemErrorDomain?: (string | null)[];
223
+ /**
224
+ * Optional domains for system error event routing
225
+ *
226
+ * @default [ArvoDomain.FROM_PARENT_SUBJECT]
227
+ */
228
+ systemErrorDomain?: NonEmptyArray<string | null>;
224
229
  /** OpenTelemetry span configuration for distributed tracing */
225
230
  spanOptions?: ArvoEventHandlerOtelSpanOptions;
231
+ /**
232
+ * Optional default domains for the events emitted
233
+ * by the orchestrator.
234
+ */
235
+ defaultEventEmissionDomains?: {
236
+ /**
237
+ * Default domains for system error events emitted by this orchestrator.
238
+ *
239
+ * System errors are routed through these domains when the handler encounters
240
+ * unhandled exceptions or critical failures.
241
+ *
242
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
243
+ */
244
+ systemError?: NonEmptyArray<string | null>;
245
+ /**
246
+ * Default domains for service events emitted by this orchestrator.
247
+ *
248
+ * The service xstate.emit function can over-ride this default.
249
+ *
250
+ * @default [ArvoDomain.LOCAL]
251
+ */
252
+ services?: NonEmptyArray<string | null>;
253
+ /**
254
+ * Defauld domain for the final completion event emitted by this orchestrator
255
+ *
256
+ * Completion event is routed through these domains when the orchestrator successfully
257
+ * processes an init event. The machine 'output' transform function implementations can override
258
+ * this default.
259
+ *
260
+ * @default [ArvoDomain.ORCHESTRATION_CONTEXT]
261
+ */
262
+ complete?: NonEmptyArray<string | null>;
263
+ };
226
264
  };
227
265
  /**
228
266
  * Configuration parameters for creating an ArvoResumable instance.
@@ -252,9 +290,8 @@ export type CreateArvoResumableParam<TMemory extends Record<string, any>, TSelfC
252
290
  * @default true if multiple service contracts, false otherwise
253
291
  */
254
292
  requiresResourceLocking?: boolean;
255
- /** Optional domains for system error event routing */
256
- systemErrorDomain?: (string | null)[];
257
293
  /** OpenTelemetry span configuration for distributed tracing */
258
294
  spanOptions?: ArvoEventHandlerOtelSpanOptions;
295
+ defaultEventEmissionDomains?: ArvoResumableParam<TMemory, TSelfContract, TServiceContract>['defaultEventEmissionDomains'];
259
296
  };
260
297
  export {};
@@ -42,9 +42,6 @@ export default interface IArvoEventHandler {
42
42
  *
43
43
  * @property type - The error event type identifier
44
44
  * @property schema - Zod schema defining the error event data structure
45
- * @property domain - Optional domains for error event routing and distribution
46
45
  */
47
- systemErrorSchema: ArvoContractRecord & {
48
- domain?: (string | null)[];
49
- };
46
+ systemErrorSchema: ArvoContractRecord;
50
47
  }
package/dist/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { SpanOptions } from '@opentelemetry/api';
2
2
  import type { ArvoEvent } from 'arvo-core';
3
3
  import type IArvoEventHandler from './IArvoEventHandler';
4
+ export type NonEmptyArray<T> = [T, ...T[]];
4
5
  /**
5
6
  * Makes properties optional except specified keys
6
7
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arvo-event-handler",
3
- "version": "3.0.23",
3
+ "version": "3.0.25",
4
4
  "description": "A complete set of orthogonal event handler and orchestration primitives for Arvo based applications, featuring declarative state machines (XState), imperative resumables for agentic workflows, contract-based routing, OpenTelemetry observability, and in-memory event broker for building composable event-driven architectures.",
5
5
  "main": "dist/index.js",
6
6
  "repository": {
@@ -65,7 +65,7 @@
65
65
  "dependencies": {
66
66
  "@opentelemetry/api": "1.9.0",
67
67
  "@opentelemetry/core": "1.30.1",
68
- "arvo-core": "3.0.23",
68
+ "arvo-core": "3.0.25",
69
69
  "uuid": "11.1.0",
70
70
  "xstate": "5.24.0",
71
71
  "zod": "3.25.74",