abxbus 2.4.32 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -51
- package/dist/cjs/BaseEvent.d.ts +46 -55
- package/dist/cjs/BaseEvent.js +350 -169
- package/dist/cjs/BaseEvent.js.map +3 -3
- package/dist/cjs/EventBus.d.ts +8 -1
- package/dist/cjs/EventBus.js +153 -85
- package/dist/cjs/EventBus.js.map +2 -2
- package/dist/cjs/EventHandler.d.ts +3 -3
- package/dist/cjs/EventHandler.js.map +1 -1
- package/dist/cjs/EventResult.js +16 -22
- package/dist/cjs/EventResult.js.map +2 -2
- package/dist/cjs/LockManager.d.ts +1 -0
- package/dist/cjs/LockManager.js +4 -1
- package/dist/cjs/LockManager.js.map +2 -2
- package/dist/cjs/events_suck.js +1 -1
- package/dist/cjs/events_suck.js.map +2 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/timing.js +1 -1
- package/dist/cjs/timing.js.map +2 -2
- package/dist/esm/BaseEvent.js +351 -170
- package/dist/esm/BaseEvent.js.map +3 -3
- package/dist/esm/EventBus.js +153 -85
- package/dist/esm/EventBus.js.map +2 -2
- package/dist/esm/EventHandler.js.map +1 -1
- package/dist/esm/EventResult.js +16 -22
- package/dist/esm/EventResult.js.map +2 -2
- package/dist/esm/LockManager.js +4 -1
- package/dist/esm/LockManager.js.map +2 -2
- package/dist/esm/events_suck.js +1 -1
- package/dist/esm/events_suck.js.map +2 -2
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/timing.js +1 -1
- package/dist/esm/timing.js.map +2 -2
- package/dist/types/BaseEvent.d.ts +46 -55
- package/dist/types/EventBus.d.ts +8 -1
- package/dist/types/EventHandler.d.ts +3 -3
- package/dist/types/LockManager.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +4 -3
- package/src/BaseEvent.ts +456 -219
- package/src/EventBus.ts +186 -99
- package/src/EventHandler.ts +3 -3
- package/src/EventResult.ts +18 -22
- package/src/LockManager.ts +5 -1
- package/src/events_suck.ts +1 -1
- package/src/index.ts +1 -0
- package/src/timing.ts +1 -1
- package/dist/cjs/base_event.d.ts +0 -211
- package/dist/cjs/bridge_jsonl.d.ts +0 -26
- package/dist/cjs/bridge_nats.d.ts +0 -20
- package/dist/cjs/bridge_postgres.d.ts +0 -31
- package/dist/cjs/bridge_redis.d.ts +0 -34
- package/dist/cjs/bridge_sqlite.d.ts +0 -30
- package/dist/cjs/event_bus.d.ts +0 -125
- package/dist/cjs/event_handler.d.ts +0 -139
- package/dist/cjs/event_history.d.ts +0 -45
- package/dist/cjs/event_result.d.ts +0 -86
- package/dist/cjs/lock_manager.d.ts +0 -70
- package/dist/types/base_event.d.ts +0 -211
- package/dist/types/bridge_jsonl.d.ts +0 -26
- package/dist/types/bridge_nats.d.ts +0 -20
- package/dist/types/bridge_postgres.d.ts +0 -31
- package/dist/types/bridge_redis.d.ts +0 -34
- package/dist/types/bridge_sqlite.d.ts +0 -30
- package/dist/types/event_bus.d.ts +0 -125
- package/dist/types/event_handler.d.ts +0 -139
- package/dist/types/event_history.d.ts +0 -45
- package/dist/types/event_result.d.ts +0 -86
- package/dist/types/lock_manager.d.ts +0 -70
package/dist/cjs/BaseEvent.js
CHANGED
|
@@ -30,7 +30,18 @@ var import_LockManager = require("./LockManager.js");
|
|
|
30
30
|
var import_timing = require("./timing.js");
|
|
31
31
|
var import_types = require("./types.js");
|
|
32
32
|
var import_helpers = require("./helpers.js");
|
|
33
|
-
const RESERVED_USER_EVENT_FIELDS = /* @__PURE__ */ new Set([
|
|
33
|
+
const RESERVED_USER_EVENT_FIELDS = /* @__PURE__ */ new Set([
|
|
34
|
+
"bus",
|
|
35
|
+
"emit",
|
|
36
|
+
"wait",
|
|
37
|
+
"now",
|
|
38
|
+
"eventResult",
|
|
39
|
+
"eventResultsList",
|
|
40
|
+
"toString",
|
|
41
|
+
"toJSON",
|
|
42
|
+
"fromJSON"
|
|
43
|
+
]);
|
|
44
|
+
const EVENT_TYPE_REGISTRY = /* @__PURE__ */ new Map();
|
|
34
45
|
function assertNoReservedUserEventFields(data, context) {
|
|
35
46
|
for (const field_name of RESERVED_USER_EVENT_FIELDS) {
|
|
36
47
|
if (Object.prototype.hasOwnProperty.call(data, field_name)) {
|
|
@@ -52,6 +63,12 @@ function assertNoModelPrefixedFields(data, context) {
|
|
|
52
63
|
}
|
|
53
64
|
}
|
|
54
65
|
}
|
|
66
|
+
function isRecord(value) {
|
|
67
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
68
|
+
}
|
|
69
|
+
function isZodObjectSchema(value) {
|
|
70
|
+
return (0, import_types.isZodSchema)(value) && typeof value.safeExtend === "function" && isRecord(value.shape);
|
|
71
|
+
}
|
|
55
72
|
function compareIsoDatetime(left, right) {
|
|
56
73
|
const left_value = left ?? "";
|
|
57
74
|
const right_value = right ?? "";
|
|
@@ -65,10 +82,10 @@ const BaseEventSchema = import_zod.z.object({
|
|
|
65
82
|
event_created_at: import_zod.z.string().datetime(),
|
|
66
83
|
event_type: import_zod.z.string(),
|
|
67
84
|
event_version: import_zod.z.string().default("0.0.1"),
|
|
68
|
-
event_timeout: import_zod.z.number().
|
|
69
|
-
event_slow_timeout: import_zod.z.number().
|
|
70
|
-
event_handler_timeout: import_zod.z.number().
|
|
71
|
-
event_handler_slow_timeout: import_zod.z.number().
|
|
85
|
+
event_timeout: import_zod.z.number().nonnegative().nullable(),
|
|
86
|
+
event_slow_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
87
|
+
event_handler_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
88
|
+
event_handler_slow_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
72
89
|
event_blocks_parent_completion: import_zod.z.boolean().optional(),
|
|
73
90
|
event_parent_id: import_zod.z.string().uuid().nullable().optional(),
|
|
74
91
|
event_path: import_zod.z.array(import_zod.z.string()).optional(),
|
|
@@ -84,8 +101,110 @@ const BaseEventSchema = import_zod.z.object({
|
|
|
84
101
|
event_handler_completion: import_zod.z.enum(import_LockManager.EVENT_HANDLER_COMPLETION_MODES).nullable().optional()
|
|
85
102
|
}).loose();
|
|
86
103
|
const KNOWN_BASE_EVENT_FIELDS = new Set(Object.keys(BaseEventSchema.shape));
|
|
87
|
-
const EVENT_CLASS_DEFAULTS = /* @__PURE__ */ new WeakMap();
|
|
88
104
|
const ROOT_EVENTBUS_ID = "00000000-0000-0000-0000-000000000000";
|
|
105
|
+
function baseEventDefaultShape(event_type) {
|
|
106
|
+
return {
|
|
107
|
+
event_id: import_zod.z.string().uuid(),
|
|
108
|
+
event_created_at: import_zod.z.string().datetime(),
|
|
109
|
+
event_type: import_zod.z.string().default(event_type),
|
|
110
|
+
event_version: import_zod.z.string().default("0.0.1"),
|
|
111
|
+
event_timeout: import_zod.z.number().nonnegative().nullable().default(null),
|
|
112
|
+
event_slow_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
113
|
+
event_handler_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
114
|
+
event_handler_slow_timeout: import_zod.z.number().nonnegative().nullable().optional(),
|
|
115
|
+
event_blocks_parent_completion: import_zod.z.boolean().default(false),
|
|
116
|
+
event_parent_id: import_zod.z.string().uuid().nullable().optional(),
|
|
117
|
+
event_path: import_zod.z.array(import_zod.z.string()).optional(),
|
|
118
|
+
event_result_type: import_zod.z.unknown().optional(),
|
|
119
|
+
event_emitted_by_handler_id: import_zod.z.string().uuid().nullable().optional(),
|
|
120
|
+
event_pending_bus_count: import_zod.z.number().nonnegative().optional(),
|
|
121
|
+
event_status: import_zod.z.enum(["pending", "started", "completed"]).optional(),
|
|
122
|
+
event_started_at: import_zod.z.string().datetime().nullable().optional(),
|
|
123
|
+
event_completed_at: import_zod.z.string().datetime().nullable().optional(),
|
|
124
|
+
event_results: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
125
|
+
event_concurrency: import_zod.z.enum(import_LockManager.EVENT_CONCURRENCY_MODES).nullable().optional(),
|
|
126
|
+
event_handler_concurrency: import_zod.z.enum(import_LockManager.EVENT_HANDLER_CONCURRENCY_MODES).nullable().optional(),
|
|
127
|
+
event_handler_completion: import_zod.z.enum(import_LockManager.EVENT_HANDLER_COMPLETION_MODES).nullable().optional()
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function missingBaseFields(event_type, user_shape) {
|
|
131
|
+
return Object.fromEntries(Object.entries(baseEventDefaultShape(event_type)).filter(([key]) => !(key in user_shape)));
|
|
132
|
+
}
|
|
133
|
+
function shortcutDefaultSchema(base_field_schema, value) {
|
|
134
|
+
if (!base_field_schema) {
|
|
135
|
+
return import_zod.z.unknown().optional().default(value);
|
|
136
|
+
}
|
|
137
|
+
return base_field_schema.prefault(base_field_schema.parse(value));
|
|
138
|
+
}
|
|
139
|
+
function schemaDefaultsForShortcut(event_type, raw_shape) {
|
|
140
|
+
const defaults = {};
|
|
141
|
+
const base_shape = baseEventDefaultShape(event_type);
|
|
142
|
+
for (const [key, value] of Object.entries(raw_shape)) {
|
|
143
|
+
if (key === "event_result_type") continue;
|
|
144
|
+
if (!(0, import_types.isZodSchema)(value)) {
|
|
145
|
+
defaults[key] = shortcutDefaultSchema(base_shape[key], value);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return defaults;
|
|
149
|
+
}
|
|
150
|
+
function zodFieldsForShortcut(raw_shape) {
|
|
151
|
+
const fields = {};
|
|
152
|
+
for (const [key, value] of Object.entries(raw_shape)) {
|
|
153
|
+
if (key === "event_result_type") continue;
|
|
154
|
+
if ((0, import_types.isZodSchema)(value)) {
|
|
155
|
+
fields[key] = value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return fields;
|
|
159
|
+
}
|
|
160
|
+
function eventResultTypeFromObjectSchema(schema) {
|
|
161
|
+
const raw_event_result_type = schema.shape.event_result_type;
|
|
162
|
+
return raw_event_result_type === void 0 ? void 0 : (0, import_types.normalizeEventResultType)(raw_event_result_type);
|
|
163
|
+
}
|
|
164
|
+
function buildFullEventSchema(event_type, spec) {
|
|
165
|
+
if (isZodObjectSchema(spec)) {
|
|
166
|
+
const user_shape = spec.shape;
|
|
167
|
+
assertNoReservedUserEventFields(user_shape, `BaseEvent.extend(${event_type})`);
|
|
168
|
+
assertNoUnknownEventPrefixedFields(user_shape, `BaseEvent.extend(${event_type})`);
|
|
169
|
+
assertNoModelPrefixedFields(user_shape, `BaseEvent.extend(${event_type})`);
|
|
170
|
+
const full_schema2 = spec.safeExtend({
|
|
171
|
+
event_result_type: import_zod.z.unknown().optional(),
|
|
172
|
+
...missingBaseFields(event_type, user_shape)
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
event_schema: full_schema2,
|
|
176
|
+
event_result_type: eventResultTypeFromObjectSchema(spec)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const raw_shape = isRecord(spec) ? spec : {};
|
|
180
|
+
assertNoReservedUserEventFields(raw_shape, `BaseEvent.extend(${event_type})`);
|
|
181
|
+
assertNoUnknownEventPrefixedFields(raw_shape, `BaseEvent.extend(${event_type})`);
|
|
182
|
+
assertNoModelPrefixedFields(raw_shape, `BaseEvent.extend(${event_type})`);
|
|
183
|
+
const shortcut_shape = {
|
|
184
|
+
...schemaDefaultsForShortcut(event_type, raw_shape),
|
|
185
|
+
...zodFieldsForShortcut(raw_shape)
|
|
186
|
+
};
|
|
187
|
+
const full_schema = import_zod.z.object(shortcut_shape).safeExtend(missingBaseFields(event_type, shortcut_shape)).loose();
|
|
188
|
+
return {
|
|
189
|
+
event_schema: full_schema,
|
|
190
|
+
event_result_type: (0, import_types.normalizeEventResultType)(raw_shape.event_result_type),
|
|
191
|
+
event_version: typeof raw_shape.event_version === "string" ? raw_shape.event_version : void 0
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function decodeEventSchema(schema, input) {
|
|
195
|
+
const decoded = import_zod.z.decode(schema, input);
|
|
196
|
+
if (!isRecord(decoded)) {
|
|
197
|
+
throw new Error("BaseEvent schema must decode to an object");
|
|
198
|
+
}
|
|
199
|
+
return decoded;
|
|
200
|
+
}
|
|
201
|
+
function encodeEventSchema(schema, input) {
|
|
202
|
+
const encoded = import_zod.z.encode(schema, input);
|
|
203
|
+
if (!isRecord(encoded)) {
|
|
204
|
+
throw new Error("BaseEvent schema must encode to an object");
|
|
205
|
+
}
|
|
206
|
+
return encoded;
|
|
207
|
+
}
|
|
89
208
|
class BaseEvent {
|
|
90
209
|
// event metadata fields
|
|
91
210
|
event_id;
|
|
@@ -104,7 +223,7 @@ class BaseEvent {
|
|
|
104
223
|
event_handler_slow_timeout;
|
|
105
224
|
// optional per-event slow handler warning threshold in seconds
|
|
106
225
|
event_blocks_parent_completion;
|
|
107
|
-
// true only for children explicitly awaited via
|
|
226
|
+
// true only for children explicitly awaited via now()
|
|
108
227
|
event_parent_id;
|
|
109
228
|
// id of the parent event that triggered this event, if this event was emitted during handling of another event, else null
|
|
110
229
|
event_path;
|
|
@@ -127,11 +246,13 @@ class BaseEvent {
|
|
|
127
246
|
// concurrency mode for the handlers within the event
|
|
128
247
|
event_handler_completion;
|
|
129
248
|
// completion strategy: 'all' (default) waits for every handler, 'first' returns earliest non-undefined result and cancels the rest
|
|
249
|
+
event_schema;
|
|
130
250
|
static event_type;
|
|
131
251
|
// class name of the event, e.g. BaseEvent.extend("MyEvent").event_type === "MyEvent"
|
|
132
252
|
static event_version = "0.0.1";
|
|
133
|
-
static
|
|
134
|
-
|
|
253
|
+
static event_result_type;
|
|
254
|
+
static event_schema = BaseEventSchema;
|
|
255
|
+
// generated Zod schema for local TS event data validation; never sent over the wire
|
|
135
256
|
// internal runtime state
|
|
136
257
|
event_bus;
|
|
137
258
|
// bus that dispatched this event, also used by event.emit(child)
|
|
@@ -139,6 +260,7 @@ class BaseEvent {
|
|
|
139
260
|
// underlying event object that was dispatched, if this is a bus-scoped proxy wrapping it
|
|
140
261
|
_event_dispatch_context;
|
|
141
262
|
// captured AsyncLocalStorage context at dispatch site, used to restore that context when running handlers
|
|
263
|
+
_event_fields_set;
|
|
142
264
|
_event_completed_signal;
|
|
143
265
|
_lock_for_event_handler;
|
|
144
266
|
constructor(data = {}) {
|
|
@@ -146,34 +268,42 @@ class BaseEvent {
|
|
|
146
268
|
assertNoUnknownEventPrefixedFields(data, "BaseEvent");
|
|
147
269
|
assertNoModelPrefixedFields(data, "BaseEvent");
|
|
148
270
|
const ctor = this.constructor;
|
|
149
|
-
const
|
|
150
|
-
const merged_data = {
|
|
151
|
-
...ctor_defaults,
|
|
152
|
-
...data
|
|
153
|
-
};
|
|
271
|
+
const explicit_event_fields = new Set(Object.keys(data ?? {}));
|
|
272
|
+
const merged_data = { ...data };
|
|
154
273
|
const event_type = merged_data.event_type ?? ctor.event_type ?? ctor.name;
|
|
155
274
|
const event_version = merged_data.event_version ?? ctor.event_version ?? "0.0.1";
|
|
156
275
|
const raw_event_result_type = merged_data.event_result_type ?? ctor.event_result_type;
|
|
157
276
|
const event_result_type = (0, import_types.normalizeEventResultType)(raw_event_result_type);
|
|
158
|
-
const
|
|
159
|
-
const event_created_at = (0, import_helpers.monotonicDatetime)(merged_data.event_created_at);
|
|
160
|
-
const event_timeout = merged_data.event_timeout ?? null;
|
|
161
|
-
const event_blocks_parent_completion = merged_data.event_blocks_parent_completion ?? false;
|
|
277
|
+
const event_schema = ctor.event_schema ?? BaseEventSchema;
|
|
162
278
|
const base_data = {
|
|
163
279
|
...merged_data,
|
|
164
|
-
event_id,
|
|
165
|
-
event_created_at,
|
|
280
|
+
event_id: merged_data.event_id ?? (0, import_uuid.v7)(),
|
|
281
|
+
event_created_at: merged_data.event_created_at ?? (0, import_helpers.monotonicDatetime)(),
|
|
166
282
|
event_type,
|
|
167
283
|
event_version,
|
|
168
|
-
event_timeout,
|
|
169
|
-
event_blocks_parent_completion,
|
|
170
284
|
event_result_type
|
|
171
285
|
};
|
|
172
|
-
|
|
173
|
-
|
|
286
|
+
if (event_schema === BaseEventSchema) {
|
|
287
|
+
base_data.event_timeout ??= null;
|
|
288
|
+
base_data.event_blocks_parent_completion ??= false;
|
|
289
|
+
}
|
|
290
|
+
const parsed = decodeEventSchema(event_schema, base_data);
|
|
174
291
|
Object.assign(this, parsed);
|
|
292
|
+
Object.defineProperty(this, "event_schema", {
|
|
293
|
+
value: event_schema,
|
|
294
|
+
writable: true,
|
|
295
|
+
enumerable: false,
|
|
296
|
+
configurable: true
|
|
297
|
+
});
|
|
298
|
+
Object.defineProperty(this, "_event_fields_set", {
|
|
299
|
+
value: explicit_event_fields,
|
|
300
|
+
writable: true,
|
|
301
|
+
enumerable: false,
|
|
302
|
+
configurable: true
|
|
303
|
+
});
|
|
175
304
|
const parsed_path = parsed.event_path;
|
|
176
305
|
this.event_path = Array.isArray(parsed_path) ? [...parsed_path] : [];
|
|
306
|
+
this.event_created_at = (0, import_helpers.monotonicDatetime)(parsed.event_created_at);
|
|
177
307
|
this.event_results = hydrateEventResults(this, parsed.event_results);
|
|
178
308
|
this.event_pending_bus_count = typeof parsed.event_pending_bus_count === "number" ? Math.max(0, Number(parsed.event_pending_bus_count)) : 0;
|
|
179
309
|
const parsed_status = parsed.event_status;
|
|
@@ -182,7 +312,7 @@ class BaseEvent {
|
|
|
182
312
|
this.event_completed_at = parsed.event_completed_at === null || parsed.event_completed_at === void 0 ? null : (0, import_helpers.monotonicDatetime)(parsed.event_completed_at);
|
|
183
313
|
this.event_parent_id = typeof parsed.event_parent_id === "string" ? parsed.event_parent_id : null;
|
|
184
314
|
this.event_emitted_by_handler_id = typeof parsed.event_emitted_by_handler_id === "string" ? parsed.event_emitted_by_handler_id : null;
|
|
185
|
-
this.event_result_type = event_result_type;
|
|
315
|
+
this.event_result_type = (0, import_types.normalizeEventResultType)(parsed.event_result_type ?? event_result_type);
|
|
186
316
|
this._event_completed_signal = null;
|
|
187
317
|
this._lock_for_event_handler = null;
|
|
188
318
|
this._event_dispatch_context = void 0;
|
|
@@ -191,23 +321,13 @@ class BaseEvent {
|
|
|
191
321
|
toString() {
|
|
192
322
|
return `${this.event_type}#${this.event_id.slice(-4)}`;
|
|
193
323
|
}
|
|
194
|
-
static extend(event_type, shape
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const raw_event_result_type = raw_shape.event_result_type;
|
|
200
|
-
const event_result_type = (0, import_types.normalizeEventResultType)(raw_event_result_type);
|
|
201
|
-
const event_version = typeof raw_shape.event_version === "string" ? raw_shape.event_version : void 0;
|
|
202
|
-
const event_defaults = Object.fromEntries(
|
|
203
|
-
Object.entries(raw_shape).filter(
|
|
204
|
-
([key, value]) => key !== "event_result_type" && key !== "event_version" && !(value instanceof import_zod.z.ZodType)
|
|
205
|
-
)
|
|
206
|
-
);
|
|
207
|
-
const zod_shape = (0, import_types.extractZodShape)(raw_shape);
|
|
208
|
-
const full_schema = BaseEventSchema.extend(zod_shape);
|
|
324
|
+
static extend(event_type, shape) {
|
|
325
|
+
const built = buildFullEventSchema(event_type, shape ?? {});
|
|
326
|
+
const full_schema = built.event_schema;
|
|
327
|
+
const event_result_type = built.event_result_type;
|
|
328
|
+
const event_version = built.event_version;
|
|
209
329
|
class ExtendedEvent extends BaseEvent {
|
|
210
|
-
static
|
|
330
|
+
static event_schema = full_schema;
|
|
211
331
|
static event_type = event_type;
|
|
212
332
|
static event_version = event_version ?? BaseEvent.event_version;
|
|
213
333
|
static event_result_type = event_result_type;
|
|
@@ -218,23 +338,36 @@ class BaseEvent {
|
|
|
218
338
|
function EventFactory(data) {
|
|
219
339
|
return new ExtendedEvent(data);
|
|
220
340
|
}
|
|
221
|
-
EventFactory.
|
|
341
|
+
EventFactory.event_schema = full_schema;
|
|
222
342
|
EventFactory.event_type = event_type;
|
|
223
343
|
EventFactory.event_version = event_version ?? BaseEvent.event_version;
|
|
224
344
|
EventFactory.event_result_type = event_result_type;
|
|
225
345
|
EventFactory.class = ExtendedEvent;
|
|
226
346
|
EventFactory.fromJSON = (data) => ExtendedEvent.fromJSON(data);
|
|
227
347
|
EventFactory.prototype = ExtendedEvent.prototype;
|
|
228
|
-
|
|
348
|
+
EVENT_TYPE_REGISTRY.set(event_type, ExtendedEvent);
|
|
229
349
|
return EventFactory;
|
|
230
350
|
}
|
|
231
351
|
static fromJSON(data) {
|
|
232
352
|
if (!data || typeof data !== "object") {
|
|
233
|
-
const
|
|
234
|
-
const parsed =
|
|
353
|
+
const event_schema = this.event_schema ?? BaseEventSchema;
|
|
354
|
+
const parsed = decodeEventSchema(event_schema, data);
|
|
235
355
|
return new this(parsed);
|
|
236
356
|
}
|
|
237
357
|
const record = { ...data };
|
|
358
|
+
if (this === BaseEvent) {
|
|
359
|
+
const event_type = record.event_type;
|
|
360
|
+
if (typeof event_type === "string") {
|
|
361
|
+
const KnownEvent = EVENT_TYPE_REGISTRY.get(event_type);
|
|
362
|
+
if (KnownEvent) {
|
|
363
|
+
return KnownEvent.fromJSON(record);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const ctor = this;
|
|
368
|
+
if (this !== BaseEvent && ctor.event_result_type && record.event_result_type !== void 0) {
|
|
369
|
+
delete record.event_result_type;
|
|
370
|
+
}
|
|
238
371
|
if (record.event_result_type !== void 0 && record.event_result_type !== null) {
|
|
239
372
|
record.event_result_type = (0, import_types.normalizeEventResultType)(record.event_result_type);
|
|
240
373
|
}
|
|
@@ -255,18 +388,47 @@ class BaseEvent {
|
|
|
255
388
|
toJSON() {
|
|
256
389
|
const record = {};
|
|
257
390
|
for (const [key, value] of Object.entries(this)) {
|
|
258
|
-
if (key.startsWith("_") || key === "bus" || key === "event_bus" || key === "event_results") continue;
|
|
391
|
+
if (key.startsWith("_") || key === "bus" || key === "event_bus" || key === "event_schema" || key === "event_results") continue;
|
|
259
392
|
if (value === void 0 || typeof value === "function") continue;
|
|
260
393
|
record[key] = value;
|
|
261
394
|
}
|
|
262
395
|
const event_results = Object.fromEntries(
|
|
263
396
|
Array.from(this.event_results.entries()).map(([handler_id, result]) => [handler_id, result.toJSON()])
|
|
264
397
|
);
|
|
265
|
-
|
|
398
|
+
const event_schema = this.constructor.event_schema ?? this.event_schema ?? BaseEventSchema;
|
|
399
|
+
const encoded = encodeEventSchema(event_schema, {
|
|
266
400
|
...record,
|
|
267
401
|
event_id: this.event_id,
|
|
268
402
|
event_type: this.event_type,
|
|
269
403
|
event_version: this.event_version,
|
|
404
|
+
event_result_type: this.event_result_type,
|
|
405
|
+
// static configuration options
|
|
406
|
+
event_timeout: this.event_timeout,
|
|
407
|
+
event_slow_timeout: this.event_slow_timeout,
|
|
408
|
+
event_concurrency: this.event_concurrency,
|
|
409
|
+
event_handler_concurrency: this.event_handler_concurrency,
|
|
410
|
+
event_handler_completion: this.event_handler_completion,
|
|
411
|
+
event_handler_slow_timeout: this.event_handler_slow_timeout,
|
|
412
|
+
event_handler_timeout: this.event_handler_timeout,
|
|
413
|
+
event_blocks_parent_completion: this.event_blocks_parent_completion,
|
|
414
|
+
// mutable parent/child/bus tracking runtime state
|
|
415
|
+
event_parent_id: this.event_parent_id,
|
|
416
|
+
event_path: this.event_path,
|
|
417
|
+
event_emitted_by_handler_id: this.event_emitted_by_handler_id,
|
|
418
|
+
event_pending_bus_count: this.event_pending_bus_count,
|
|
419
|
+
// mutable runtime status and timestamps
|
|
420
|
+
event_status: this.event_status,
|
|
421
|
+
event_created_at: this.event_created_at,
|
|
422
|
+
event_started_at: this.event_started_at ?? null,
|
|
423
|
+
event_completed_at: this.event_completed_at ?? null,
|
|
424
|
+
...Object.keys(event_results).length > 0 ? { event_results } : {}
|
|
425
|
+
});
|
|
426
|
+
delete encoded.event_schema;
|
|
427
|
+
return {
|
|
428
|
+
...encoded,
|
|
429
|
+
event_id: this.event_id,
|
|
430
|
+
event_type: this.event_type,
|
|
431
|
+
event_version: this.event_version,
|
|
270
432
|
event_result_type: this.event_result_type ? (0, import_types.toJsonSchema)(this.event_result_type) : this.event_result_type,
|
|
271
433
|
// static configuration options
|
|
272
434
|
event_timeout: this.event_timeout,
|
|
@@ -291,13 +453,12 @@ class BaseEvent {
|
|
|
291
453
|
...Object.keys(event_results).length > 0 ? { event_results } : {}
|
|
292
454
|
};
|
|
293
455
|
}
|
|
294
|
-
_createSlowEventWarningTimer() {
|
|
295
|
-
const
|
|
296
|
-
const event_warn_ms = event_slow_timeout === null ? null : event_slow_timeout * 1e3;
|
|
456
|
+
_createSlowEventWarningTimer(event_slow_timeout = this.event_slow_timeout ?? null, bus_name) {
|
|
457
|
+
const event_warn_ms = event_slow_timeout === null || event_slow_timeout <= 0 ? null : event_slow_timeout * 1e3;
|
|
297
458
|
if (event_warn_ms === null) {
|
|
298
459
|
return null;
|
|
299
460
|
}
|
|
300
|
-
const name = this.event_bus?.name ?? "EventBus";
|
|
461
|
+
const name = bus_name ?? this.event_bus?.name ?? "EventBus";
|
|
301
462
|
return setTimeout(() => {
|
|
302
463
|
if (this.event_status === "completed") {
|
|
303
464
|
return;
|
|
@@ -383,7 +544,13 @@ class BaseEvent {
|
|
|
383
544
|
return Array.from(original.event_results.values()).filter((result) => result.eventbus_id === this.event_bus.id);
|
|
384
545
|
}
|
|
385
546
|
_isFirstModeWinningResult(entry) {
|
|
386
|
-
return
|
|
547
|
+
return BaseEvent._defaultResultInclude(entry.result, entry);
|
|
548
|
+
}
|
|
549
|
+
static _defaultResultInclude(result, event_result) {
|
|
550
|
+
return event_result.status === "completed" && result !== void 0 && result !== null && !(result instanceof Error) && !(result instanceof BaseEvent) && event_result.error === void 0;
|
|
551
|
+
}
|
|
552
|
+
static _includeEventResult(include, event_result) {
|
|
553
|
+
return include(event_result.result, event_result);
|
|
387
554
|
}
|
|
388
555
|
_markFirstModeWinnerIfNeeded(original, entry, first_state) {
|
|
389
556
|
if (first_state.found || !this._isFirstModeWinningResult(entry)) {
|
|
@@ -396,9 +563,13 @@ class BaseEvent {
|
|
|
396
563
|
if (!this.event_bus) {
|
|
397
564
|
throw new Error("event has no bus attached");
|
|
398
565
|
}
|
|
399
|
-
await this.event_bus.locks._runWithHandlerLock(
|
|
400
|
-
|
|
401
|
-
|
|
566
|
+
await this.event_bus.locks._runWithHandlerLock(
|
|
567
|
+
original,
|
|
568
|
+
original.event_handler_concurrency ?? this.event_bus.event_handler_concurrency,
|
|
569
|
+
async (handler_lock) => {
|
|
570
|
+
await entry.runHandler(handler_lock);
|
|
571
|
+
}
|
|
572
|
+
);
|
|
402
573
|
}
|
|
403
574
|
// Run all pending handler results for the current bus context.
|
|
404
575
|
async _runHandlers(pending_entries) {
|
|
@@ -409,7 +580,7 @@ class BaseEvent {
|
|
|
409
580
|
}
|
|
410
581
|
const resolved_completion = original.event_handler_completion ?? this.event_bus?.event_handler_completion ?? "all";
|
|
411
582
|
if (resolved_completion === "first") {
|
|
412
|
-
if (original._getHandlerLock(this.event_bus?.event_handler_concurrency) !== null) {
|
|
583
|
+
if (original._getHandlerLock(original.event_handler_concurrency ?? this.event_bus?.event_handler_concurrency ?? "serial") !== null) {
|
|
413
584
|
for (const entry of pending_results) {
|
|
414
585
|
await this._runHandlerWithLock(original, entry);
|
|
415
586
|
if (!this._isFirstModeWinningResult(entry)) {
|
|
@@ -436,7 +607,7 @@ class BaseEvent {
|
|
|
436
607
|
}
|
|
437
608
|
_getHandlerLock(default_concurrency) {
|
|
438
609
|
const original = this._event_original ?? this;
|
|
439
|
-
const resolved = original.event_handler_concurrency ?? default_concurrency ??
|
|
610
|
+
const resolved = original.event_handler_concurrency ?? default_concurrency ?? "serial";
|
|
440
611
|
if (resolved === "parallel") {
|
|
441
612
|
return null;
|
|
442
613
|
}
|
|
@@ -548,18 +719,18 @@ class BaseEvent {
|
|
|
548
719
|
cancelChildEvent(child);
|
|
549
720
|
}
|
|
550
721
|
}
|
|
551
|
-
// Cancel all handler results for an event except the winner, used by first
|
|
722
|
+
// Cancel all handler results for an event except the winner, used by event_handler_completion='first'.
|
|
552
723
|
// Cancels pending handlers immediately, aborts started handlers via _signalAbort(),
|
|
553
724
|
// and cancels any child events emitted by the losing handlers.
|
|
554
725
|
_markRemainingFirstModeResultCancelled(winner) {
|
|
555
|
-
const cause = new Error("first
|
|
726
|
+
const cause = new Error("event_handler_completion='first' resolved: another handler returned a result first");
|
|
556
727
|
const bus_id = winner.eventbus_id;
|
|
557
728
|
for (const result of this.event_results.values()) {
|
|
558
729
|
if (result === winner) continue;
|
|
559
730
|
if (result.eventbus_id !== bus_id) continue;
|
|
560
731
|
if (result.status === "pending") {
|
|
561
732
|
result._markError(
|
|
562
|
-
new import_EventHandler.EventHandlerCancelledError(`Cancelled: first
|
|
733
|
+
new import_EventHandler.EventHandlerCancelledError(`Cancelled: event_handler_completion='first' resolved`, {
|
|
563
734
|
event_result: result,
|
|
564
735
|
cause
|
|
565
736
|
})
|
|
@@ -574,7 +745,7 @@ class BaseEvent {
|
|
|
574
745
|
original_child._markCancelled(cause);
|
|
575
746
|
}
|
|
576
747
|
result._lock?.exitHandlerRun();
|
|
577
|
-
const aborted_error = new import_EventHandler.EventHandlerAbortedError(`Aborted: first
|
|
748
|
+
const aborted_error = new import_EventHandler.EventHandlerAbortedError(`Aborted: event_handler_completion='first' resolved`, {
|
|
578
749
|
event_result: result,
|
|
579
750
|
cause
|
|
580
751
|
});
|
|
@@ -651,92 +822,41 @@ class BaseEvent {
|
|
|
651
822
|
parent_id = parent.event_parent_id;
|
|
652
823
|
}
|
|
653
824
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
return
|
|
659
|
-
}
|
|
825
|
+
_withEventResultMethods(promise) {
|
|
826
|
+
const chainable = promise;
|
|
827
|
+
chainable.eventResult = async (options) => {
|
|
828
|
+
const event = await promise;
|
|
829
|
+
return event.eventResult(options);
|
|
830
|
+
};
|
|
831
|
+
chainable.eventResultsList = async (options) => {
|
|
832
|
+
const event = await promise;
|
|
833
|
+
return event.eventResultsList(options);
|
|
834
|
+
};
|
|
835
|
+
return chainable;
|
|
836
|
+
}
|
|
837
|
+
_timeoutPromise(timeout, message, fn) {
|
|
838
|
+
return timeout === null || timeout <= 0 ? fn() : (0, import_timing._runWithTimeout)(timeout, () => new Error(message()), fn);
|
|
839
|
+
}
|
|
840
|
+
_orderedEventResults() {
|
|
660
841
|
const original = this._event_original ?? this;
|
|
661
|
-
original.
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (!raise_if_any) {
|
|
665
|
-
return completion_promise;
|
|
666
|
-
}
|
|
667
|
-
return completion_promise.then((completed_event) => {
|
|
668
|
-
const first_error = completed_event._firstProcessingError();
|
|
669
|
-
if (first_error !== void 0) {
|
|
670
|
-
if (first_error instanceof Error) {
|
|
671
|
-
throw first_error;
|
|
672
|
-
}
|
|
673
|
-
throw new Error(String(first_error));
|
|
674
|
-
}
|
|
675
|
-
return completed_event;
|
|
676
|
-
});
|
|
842
|
+
return Array.from(original.event_results.values()).sort(
|
|
843
|
+
(a, b) => compareIsoDatetime(a.completed_at, b.completed_at)
|
|
844
|
+
);
|
|
677
845
|
}
|
|
678
|
-
|
|
679
|
-
// when any handler completes. Works with all event_handler_concurrency modes:
|
|
680
|
-
// parallel: races all handlers, returns first non-undefined, aborts the rest
|
|
681
|
-
// serial: runs handlers sequentially, returns first non-undefined, skips remaining
|
|
682
|
-
first() {
|
|
683
|
-
if (!this.event_bus) {
|
|
684
|
-
return Promise.reject(new Error("event has no bus attached"));
|
|
685
|
-
}
|
|
846
|
+
_orderedEventResultsByRegistration() {
|
|
686
847
|
const original = this._event_original ?? this;
|
|
687
|
-
original.
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
if (first_error !== void 0) {
|
|
691
|
-
if (first_error instanceof Error) {
|
|
692
|
-
throw first_error;
|
|
693
|
-
}
|
|
694
|
-
throw new Error(String(first_error));
|
|
695
|
-
}
|
|
696
|
-
const orig = completed_event._event_original ?? completed_event;
|
|
697
|
-
return Array.from(orig.event_results.values()).filter(
|
|
698
|
-
(result) => result.status === "completed" && result.result !== void 0 && result.result !== null && !(result.result instanceof BaseEvent)
|
|
699
|
-
).sort((a, b) => compareIsoDatetime(a.completed_at, b.completed_at)).map((result) => result.result).at(0);
|
|
700
|
-
});
|
|
848
|
+
return Array.from(original.event_results.values()).sort(
|
|
849
|
+
(a, b) => compareIsoDatetime(a.handler.handler_registered_at, b.handler.handler_registered_at) || compareIsoDatetime(a.started_at, b.started_at) || a.handler_id.localeCompare(b.handler_id)
|
|
850
|
+
);
|
|
701
851
|
}
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
let options;
|
|
705
|
-
let include;
|
|
706
|
-
if (typeof include_or_options === "function") {
|
|
707
|
-
options = maybe_options ?? {};
|
|
708
|
-
include = include_or_options;
|
|
709
|
-
} else {
|
|
710
|
-
options = include_or_options ?? {};
|
|
711
|
-
include = options.include ?? default_include;
|
|
712
|
-
}
|
|
852
|
+
_collectResultValues(options = {}, order = "completion") {
|
|
853
|
+
const include = options.include ?? BaseEvent._defaultResultInclude;
|
|
713
854
|
const raise_if_any = options.raise_if_any ?? true;
|
|
714
|
-
const raise_if_none = options.raise_if_none ??
|
|
715
|
-
const
|
|
716
|
-
const resolved_timeout_seconds = options.timeout ?? original.event_timeout ?? this.event_bus?.event_timeout ?? null;
|
|
717
|
-
let completed_event;
|
|
718
|
-
if (resolved_timeout_seconds === null) {
|
|
719
|
-
completed_event = await this.done({ raise_if_any: false });
|
|
720
|
-
} else {
|
|
721
|
-
completed_event = await (0, import_timing._runWithTimeout)(
|
|
722
|
-
resolved_timeout_seconds,
|
|
723
|
-
() => new Error(`Timed out waiting for ${original.event_type} results after ${resolved_timeout_seconds}s`),
|
|
724
|
-
() => this.done({ raise_if_any: false })
|
|
725
|
-
);
|
|
726
|
-
}
|
|
727
|
-
const all_results = Array.from(completed_event.event_results.values());
|
|
855
|
+
const raise_if_none = options.raise_if_none ?? false;
|
|
856
|
+
const all_results = order === "registration" ? this._orderedEventResultsByRegistration() : this._orderedEventResults();
|
|
728
857
|
const error_results = all_results.filter((event_result) => event_result.error !== void 0 || event_result.result instanceof Error);
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
const first_error = error_results[0];
|
|
732
|
-
if (first_error.error instanceof Error) {
|
|
733
|
-
throw first_error.error;
|
|
734
|
-
}
|
|
735
|
-
if (first_error.result instanceof Error) {
|
|
736
|
-
throw first_error.result;
|
|
737
|
-
}
|
|
738
|
-
throw new Error(String(first_error.error ?? first_error.result));
|
|
739
|
-
}
|
|
858
|
+
const included_results = all_results.filter((event_result) => BaseEvent._includeEventResult(include, event_result));
|
|
859
|
+
if (error_results.length > 0 && raise_if_any) {
|
|
740
860
|
const errors = error_results.map((event_result) => {
|
|
741
861
|
if (event_result.error instanceof Error) {
|
|
742
862
|
return event_result.error;
|
|
@@ -746,28 +866,104 @@ class BaseEvent {
|
|
|
746
866
|
}
|
|
747
867
|
return new Error(String(event_result.error ?? event_result.result));
|
|
748
868
|
});
|
|
749
|
-
|
|
750
|
-
errors
|
|
751
|
-
|
|
752
|
-
);
|
|
869
|
+
if (errors.length === 1) {
|
|
870
|
+
throw errors[0];
|
|
871
|
+
}
|
|
872
|
+
throw new AggregateError(errors, `Event ${this.event_type}#${this.event_id.slice(-4)} had ${errors.length} handler error(s)`);
|
|
753
873
|
}
|
|
754
|
-
const included_results = all_results.filter((event_result) => include(event_result.result, event_result));
|
|
755
874
|
if (raise_if_none && included_results.length === 0) {
|
|
756
875
|
throw new Error(
|
|
757
|
-
`Expected at least one handler to return a non-null result, but none did: ${
|
|
876
|
+
`Expected at least one handler to return a non-null result, but none did: ${this.event_type}#${this.event_id.slice(-4)}`
|
|
758
877
|
);
|
|
759
878
|
}
|
|
760
879
|
return included_results.map((event_result) => event_result.result);
|
|
761
880
|
}
|
|
762
|
-
|
|
763
|
-
|
|
881
|
+
_hasIncludedResult(options = {}) {
|
|
882
|
+
const include = options.include ?? BaseEvent._defaultResultInclude;
|
|
883
|
+
return this._orderedEventResults().some((event_result) => BaseEvent._includeEventResult(include, event_result));
|
|
884
|
+
}
|
|
885
|
+
async _waitForFirstResultOrCompletion(options = {}) {
|
|
764
886
|
const original = this._event_original ?? this;
|
|
887
|
+
if (options.timeout !== void 0 && options.timeout !== null && options.timeout < 0) {
|
|
888
|
+
throw new Error("timeout must be >= 0 or null");
|
|
889
|
+
}
|
|
890
|
+
if (!this.event_bus && original.event_status !== "completed") {
|
|
891
|
+
throw new Error("event has no bus attached");
|
|
892
|
+
}
|
|
893
|
+
if (original.event_status === "completed" || this._hasIncludedResult(options)) {
|
|
894
|
+
return this;
|
|
895
|
+
}
|
|
896
|
+
const waitForResult = async () => {
|
|
897
|
+
for (; ; ) {
|
|
898
|
+
if (original.event_status === "completed" || this._hasIncludedResult(options)) {
|
|
899
|
+
return this;
|
|
900
|
+
}
|
|
901
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
const timeout = options.timeout ?? null;
|
|
905
|
+
return this._timeoutPromise(timeout, () => `Timed out waiting for ${original.event_type} result after ${timeout}s`, waitForResult);
|
|
906
|
+
}
|
|
907
|
+
// Active awaitable that triggers immediate (queue-jump) processing of the event on all buses where it is queued.
|
|
908
|
+
now(options = {}) {
|
|
909
|
+
const original = this._event_original ?? this;
|
|
910
|
+
if (options.timeout !== void 0 && options.timeout !== null && options.timeout < 0) {
|
|
911
|
+
return this._withEventResultMethods(Promise.reject(new Error("timeout must be >= 0 or null")));
|
|
912
|
+
}
|
|
913
|
+
if (!this.event_bus && original.event_status !== "completed") {
|
|
914
|
+
return this._withEventResultMethods(Promise.reject(new Error("event has no bus attached")));
|
|
915
|
+
}
|
|
765
916
|
original._markBlocksParentCompletionIfAwaitedFromEmittingHandler();
|
|
766
|
-
|
|
767
|
-
|
|
917
|
+
const resolved_timeout_seconds = options.timeout ?? null;
|
|
918
|
+
const processing = original.event_status === "completed" ? Promise.resolve(this) : this._timeoutPromise(
|
|
919
|
+
resolved_timeout_seconds,
|
|
920
|
+
() => `Timed out waiting for ${original.event_type} completion after ${resolved_timeout_seconds}s`,
|
|
921
|
+
() => this.event_bus._processEventImmediately(this)
|
|
922
|
+
);
|
|
923
|
+
if (options.first_result) {
|
|
924
|
+
void processing.catch(() => void 0);
|
|
925
|
+
return this._withEventResultMethods(this._waitForFirstResultOrCompletion(options));
|
|
926
|
+
}
|
|
927
|
+
return this._withEventResultMethods(processing);
|
|
928
|
+
}
|
|
929
|
+
// Passive awaitable that waits for normal queue-order processing without forcing execution.
|
|
930
|
+
wait(options = {}) {
|
|
931
|
+
const original = this._event_original ?? this;
|
|
932
|
+
if (options.timeout !== void 0 && options.timeout !== null && options.timeout < 0) {
|
|
933
|
+
return this._withEventResultMethods(Promise.reject(new Error("timeout must be >= 0 or null")));
|
|
934
|
+
}
|
|
935
|
+
if (!this.event_bus && original.event_status !== "completed") {
|
|
936
|
+
return this._withEventResultMethods(Promise.reject(new Error("event has no bus attached")));
|
|
937
|
+
}
|
|
938
|
+
if (options.first_result) {
|
|
939
|
+
return this._withEventResultMethods(this._waitForFirstResultOrCompletion(options));
|
|
940
|
+
}
|
|
941
|
+
if (original.event_status === "completed") {
|
|
942
|
+
return this._withEventResultMethods(Promise.resolve(this));
|
|
768
943
|
}
|
|
769
944
|
this._notifyDoneListeners();
|
|
770
|
-
|
|
945
|
+
const timeout = options.timeout ?? null;
|
|
946
|
+
return this._withEventResultMethods(
|
|
947
|
+
this._timeoutPromise(
|
|
948
|
+
timeout,
|
|
949
|
+
() => `Timed out waiting for ${original.event_type} completion after ${timeout}s`,
|
|
950
|
+
() => this._event_completed_signal.promise.then(() => this)
|
|
951
|
+
)
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
async eventResult(options = {}) {
|
|
955
|
+
const original = this._event_original ?? this;
|
|
956
|
+
if (original.event_status === "pending" && original.event_results.size === 0) {
|
|
957
|
+
await this.now({ first_result: true });
|
|
958
|
+
}
|
|
959
|
+
return this._collectResultValues(options, "registration").at(0);
|
|
960
|
+
}
|
|
961
|
+
async eventResultsList(options = {}) {
|
|
962
|
+
const original = this._event_original ?? this;
|
|
963
|
+
if (original.event_status === "pending" && original.event_results.size === 0) {
|
|
964
|
+
await this.now({ first_result: false });
|
|
965
|
+
}
|
|
966
|
+
return this._collectResultValues(options, "registration");
|
|
771
967
|
}
|
|
772
968
|
_markBlocksParentCompletionIfAwaitedFromEmittingHandler() {
|
|
773
969
|
const original = this._event_original ?? this;
|
|
@@ -861,23 +1057,8 @@ class BaseEvent {
|
|
|
861
1057
|
get event_errors() {
|
|
862
1058
|
return Array.from(this.event_results.values()).filter((event_result) => event_result.error !== void 0 && event_result.completed_at !== null).sort((event_result_a, event_result_b) => compareIsoDatetime(event_result_a.completed_at, event_result_b.completed_at)).map((event_result) => event_result.error);
|
|
863
1059
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return false;
|
|
867
|
-
}
|
|
868
|
-
if (error.message.includes("first() resolved")) {
|
|
869
|
-
return true;
|
|
870
|
-
}
|
|
871
|
-
return error.cause instanceof Error && error.cause.message.includes("first() resolved");
|
|
872
|
-
}
|
|
873
|
-
_firstProcessingError(options = {}) {
|
|
874
|
-
const ignore_first_mode_control_errors = options.ignore_first_mode_control_errors ?? false;
|
|
875
|
-
return Array.from(this.event_results.values()).filter((event_result) => event_result.error !== void 0 && event_result.completed_at !== null).filter((event_result) => ignore_first_mode_control_errors ? !this._isFirstModeControlError(event_result.error) : true).sort((event_result_a, event_result_b) => compareIsoDatetime(event_result_a.completed_at, event_result_b.completed_at)).map((event_result) => event_result.error).at(0);
|
|
876
|
-
}
|
|
877
|
-
// Returns the first non-undefined completed handler result, sorted by completion time.
|
|
878
|
-
// Useful after first() or done() to get the winning result value.
|
|
879
|
-
get event_result() {
|
|
880
|
-
return Array.from(this.event_results.values()).filter((event_result) => event_result.completed_at !== null && event_result.result !== void 0).sort((event_result_a, event_result_b) => compareIsoDatetime(event_result_a.completed_at, event_result_b.completed_at)).map((event_result) => event_result.result).at(0);
|
|
1060
|
+
_firstProcessingError() {
|
|
1061
|
+
return Array.from(this.event_results.values()).filter((event_result) => event_result.error !== void 0 && event_result.completed_at !== null).sort((event_result_a, event_result_b) => compareIsoDatetime(event_result_a.completed_at, event_result_b.completed_at)).map((event_result) => event_result.error).at(0);
|
|
881
1062
|
}
|
|
882
1063
|
_areAllChildrenComplete(visited = /* @__PURE__ */ new Set()) {
|
|
883
1064
|
const original = this._event_original ?? this;
|