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.
Files changed (70) hide show
  1. package/README.md +74 -51
  2. package/dist/cjs/BaseEvent.d.ts +46 -55
  3. package/dist/cjs/BaseEvent.js +350 -169
  4. package/dist/cjs/BaseEvent.js.map +3 -3
  5. package/dist/cjs/EventBus.d.ts +8 -1
  6. package/dist/cjs/EventBus.js +153 -85
  7. package/dist/cjs/EventBus.js.map +2 -2
  8. package/dist/cjs/EventHandler.d.ts +3 -3
  9. package/dist/cjs/EventHandler.js.map +1 -1
  10. package/dist/cjs/EventResult.js +16 -22
  11. package/dist/cjs/EventResult.js.map +2 -2
  12. package/dist/cjs/LockManager.d.ts +1 -0
  13. package/dist/cjs/LockManager.js +4 -1
  14. package/dist/cjs/LockManager.js.map +2 -2
  15. package/dist/cjs/events_suck.js +1 -1
  16. package/dist/cjs/events_suck.js.map +2 -2
  17. package/dist/cjs/index.d.ts +1 -0
  18. package/dist/cjs/index.js.map +2 -2
  19. package/dist/cjs/timing.js +1 -1
  20. package/dist/cjs/timing.js.map +2 -2
  21. package/dist/esm/BaseEvent.js +351 -170
  22. package/dist/esm/BaseEvent.js.map +3 -3
  23. package/dist/esm/EventBus.js +153 -85
  24. package/dist/esm/EventBus.js.map +2 -2
  25. package/dist/esm/EventHandler.js.map +1 -1
  26. package/dist/esm/EventResult.js +16 -22
  27. package/dist/esm/EventResult.js.map +2 -2
  28. package/dist/esm/LockManager.js +4 -1
  29. package/dist/esm/LockManager.js.map +2 -2
  30. package/dist/esm/events_suck.js +1 -1
  31. package/dist/esm/events_suck.js.map +2 -2
  32. package/dist/esm/index.js.map +2 -2
  33. package/dist/esm/timing.js +1 -1
  34. package/dist/esm/timing.js.map +2 -2
  35. package/dist/types/BaseEvent.d.ts +46 -55
  36. package/dist/types/EventBus.d.ts +8 -1
  37. package/dist/types/EventHandler.d.ts +3 -3
  38. package/dist/types/LockManager.d.ts +1 -0
  39. package/dist/types/index.d.ts +1 -0
  40. package/package.json +4 -3
  41. package/src/BaseEvent.ts +456 -219
  42. package/src/EventBus.ts +186 -99
  43. package/src/EventHandler.ts +3 -3
  44. package/src/EventResult.ts +18 -22
  45. package/src/LockManager.ts +5 -1
  46. package/src/events_suck.ts +1 -1
  47. package/src/index.ts +1 -0
  48. package/src/timing.ts +1 -1
  49. package/dist/cjs/base_event.d.ts +0 -211
  50. package/dist/cjs/bridge_jsonl.d.ts +0 -26
  51. package/dist/cjs/bridge_nats.d.ts +0 -20
  52. package/dist/cjs/bridge_postgres.d.ts +0 -31
  53. package/dist/cjs/bridge_redis.d.ts +0 -34
  54. package/dist/cjs/bridge_sqlite.d.ts +0 -30
  55. package/dist/cjs/event_bus.d.ts +0 -125
  56. package/dist/cjs/event_handler.d.ts +0 -139
  57. package/dist/cjs/event_history.d.ts +0 -45
  58. package/dist/cjs/event_result.d.ts +0 -86
  59. package/dist/cjs/lock_manager.d.ts +0 -70
  60. package/dist/types/base_event.d.ts +0 -211
  61. package/dist/types/bridge_jsonl.d.ts +0 -26
  62. package/dist/types/bridge_nats.d.ts +0 -20
  63. package/dist/types/bridge_postgres.d.ts +0 -31
  64. package/dist/types/bridge_redis.d.ts +0 -34
  65. package/dist/types/bridge_sqlite.d.ts +0 -30
  66. package/dist/types/event_bus.d.ts +0 -125
  67. package/dist/types/event_handler.d.ts +0 -139
  68. package/dist/types/event_history.d.ts +0 -45
  69. package/dist/types/event_result.d.ts +0 -86
  70. package/dist/types/lock_manager.d.ts +0 -70
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/EventBus.ts"],
4
- "sourcesContent": ["import { BaseEvent, type BaseEventJSON } from './BaseEvent.js'\nimport { EventHistory } from './EventHistory.js'\nimport { EventResult } from './EventResult.js'\nimport { captureAsyncContext } from './async_context.js'\nimport { _runWithSlowMonitor, _runWithTimeout } from './timing.js'\nimport {\n AsyncLock,\n type EventConcurrencyMode,\n type EventHandlerConcurrencyMode,\n type EventHandlerCompletionMode,\n LockManager,\n} from './LockManager.js'\nimport {\n EventHandler,\n EventHandlerAbortedError,\n EventHandlerCancelledError,\n EventHandlerTimeoutError,\n type EphemeralFindEventHandler,\n type EventHandlerJSON,\n} from './EventHandler.js'\nimport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './EventBusMiddleware.js'\nimport { logTree } from './logging.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport { monotonicDatetime } from './helpers.js'\n\nimport { normalizeEventPattern } from './types.js'\nimport type { EventClass, EventHandlerCallable, EventPattern, FilterOptions, FindOptions, UntypedEventHandlerFunction } from './types.js'\n\nexport type EventBusOptions = {\n id?: string\n max_history_size?: number | null\n max_history_drop?: boolean\n\n // per-event options\n event_concurrency?: EventConcurrencyMode | null\n event_timeout?: number | null // default handler timeout in seconds, applied when event.event_timeout is undefined\n event_slow_timeout?: number | null // threshold before a warning is logged about slow event processing\n\n // per-event-handler options\n event_handler_concurrency?: EventHandlerConcurrencyMode | null\n event_handler_completion?: EventHandlerCompletionMode\n event_handler_slow_timeout?: number | null // threshold before a warning is logged about slow handler execution\n event_handler_detect_file_paths?: boolean // autodetect source code file and lineno where handlers are defined for better logs (slightly slower because Error().stack introspection to fine files is expensive)\n middlewares?: EventBusMiddlewareInput[]\n}\n\nexport type EventBusJSON = {\n id: string\n name: string\n max_history_size: number | null\n max_history_drop: boolean\n event_concurrency: EventConcurrencyMode\n event_timeout: number | null\n event_slow_timeout: number | null\n event_handler_concurrency: EventHandlerConcurrencyMode\n event_handler_completion: EventHandlerCompletionMode\n event_handler_slow_timeout: number | null\n event_handler_detect_file_paths: boolean\n handlers: Record<string, EventHandlerJSON>\n handlers_by_key: Record<string, string[]>\n event_history: Record<string, BaseEventJSON>\n pending_event_queue: string[]\n}\n\n// Global registry of all EventBus instances to allow for cross-bus coordination\n// when global-serial concurrency mode is used.\nexport class GlobalEventBusRegistry {\n private _bus_refs = new Set<WeakRef<EventBus>>()\n\n add(bus: EventBus): void {\n this._bus_refs.add(new WeakRef(bus))\n }\n\n discard(bus: EventBus): void {\n for (const ref of this._bus_refs) {\n const current = ref.deref()\n if (!current || current === bus) {\n this._bus_refs.delete(ref)\n }\n }\n }\n\n has(bus: EventBus): boolean {\n for (const ref of this._bus_refs) {\n const current = ref.deref()\n if (!current) {\n this._bus_refs.delete(ref)\n continue\n }\n if (current === bus) {\n return true\n }\n }\n return false\n }\n\n get size(): number {\n let count = 0\n for (const ref of this._bus_refs) {\n if (ref.deref()) {\n count += 1\n } else {\n this._bus_refs.delete(ref)\n }\n }\n return count\n }\n\n *[Symbol.iterator](): IterableIterator<EventBus> {\n for (const ref of this._bus_refs) {\n const bus = ref.deref()\n if (bus) {\n yield bus\n } else {\n this._bus_refs.delete(ref)\n }\n }\n }\n\n findBusById(bus_id: string): EventBus | undefined {\n for (const bus of this) {\n if (bus.id === bus_id) {\n return bus\n }\n }\n return undefined\n }\n\n findEventById(event_id: string): BaseEvent | null {\n for (const bus of this) {\n const event = bus.event_history.getEvent(event_id)\n if (event) {\n return event\n }\n }\n return null\n }\n}\n\nexport class EventBus {\n private static _registry_by_constructor = new WeakMap<Function, GlobalEventBusRegistry>()\n private static _global_event_lock_by_constructor = new WeakMap<Function, AsyncLock>()\n\n private static getRegistryForConstructor(constructor_fn: Function): GlobalEventBusRegistry {\n const existing_registry = EventBus._registry_by_constructor.get(constructor_fn)\n if (existing_registry) {\n return existing_registry\n }\n const created_registry = new GlobalEventBusRegistry()\n EventBus._registry_by_constructor.set(constructor_fn, created_registry)\n return created_registry\n }\n\n private static getGlobalEventLockForConstructor(constructor_fn: Function): AsyncLock {\n const existing_lock = EventBus._global_event_lock_by_constructor.get(constructor_fn)\n if (existing_lock) {\n return existing_lock\n }\n const created_lock = new AsyncLock(1)\n EventBus._global_event_lock_by_constructor.set(constructor_fn, created_lock)\n return created_lock\n }\n\n static get all_instances(): GlobalEventBusRegistry {\n return EventBus.getRegistryForConstructor(this)\n }\n\n get all_instances(): GlobalEventBusRegistry {\n return EventBus.getRegistryForConstructor(this.constructor as Function)\n }\n\n get _lock_for_event_global_serial(): AsyncLock {\n return EventBus.getGlobalEventLockForConstructor(this.constructor as Function)\n }\n\n id: string // unique uuidv7 identifier for the event bus\n name: string // name of the event bus, recommended to include the word \"Bus\" in the name for clarity in logs\n\n // configuration options\n event_timeout: number | null\n event_concurrency: EventConcurrencyMode\n event_handler_concurrency: EventHandlerConcurrencyMode\n event_handler_completion: EventHandlerCompletionMode\n event_handler_detect_file_paths: boolean\n\n // slow processing warning timeout settings\n event_handler_slow_timeout: number | null\n event_slow_timeout: number | null\n\n // public runtime state\n handlers: Map<string, EventHandler> // map of handler uuidv5 ids to EventHandler objects\n handlers_by_key: Map<string, string[]> // map of normalized event_pattern to ordered handler ids\n event_history: EventHistory<BaseEvent> // map of event uuidv7 ids to processed BaseEvent objects\n\n // internal runtime state\n pending_event_queue: BaseEvent[] // queue of events that have been emitted to the bus but not yet processed\n in_flight_event_ids: Set<string> // set of event ids that are currently being processed by the bus\n runloop_running: boolean\n locks: LockManager\n find_waiters: Set<EphemeralFindEventHandler> // set of EphemeralFindEventHandler objects that are waiting for a matching future event\n middlewares: EventBusMiddleware[]\n\n private static normalizeMiddlewares(middlewares?: EventBusMiddlewareInput[]): EventBusMiddleware[] {\n const normalized: EventBusMiddleware[] = []\n for (const middleware of middlewares ?? []) {\n if (!middleware) {\n continue\n }\n if (typeof middleware === 'function') {\n normalized.push(new (middleware as EventBusMiddlewareCtor)())\n } else {\n normalized.push(middleware as EventBusMiddleware)\n }\n }\n return normalized\n }\n\n constructor(name: string = 'EventBus', options: EventBusOptions = {}) {\n this.id = options.id ?? uuidv7()\n this.name = name\n\n // set configuration options\n this.event_concurrency = options.event_concurrency ?? 'bus-serial'\n this.event_handler_concurrency = options.event_handler_concurrency ?? 'serial'\n this.event_handler_completion = options.event_handler_completion ?? 'all'\n this.event_handler_detect_file_paths = options.event_handler_detect_file_paths ?? true\n this.event_timeout = options.event_timeout === undefined ? 60 : options.event_timeout\n this.event_handler_slow_timeout = options.event_handler_slow_timeout === undefined ? 30 : options.event_handler_slow_timeout\n this.event_slow_timeout = options.event_slow_timeout === undefined ? 300 : options.event_slow_timeout\n\n // initialize runtime state\n this.runloop_running = false\n this.handlers = new Map()\n this.handlers_by_key = new Map()\n this.find_waiters = new Set()\n this.event_history = new EventHistory({\n max_history_size: options.max_history_size === undefined ? 100 : options.max_history_size,\n max_history_drop: options.max_history_drop ?? false,\n })\n this.pending_event_queue = []\n this.in_flight_event_ids = new Set()\n this.locks = new LockManager(this)\n this.middlewares = EventBus.normalizeMiddlewares(options.middlewares)\n\n this.all_instances.add(this)\n\n this.dispatch = this.dispatch.bind(this)\n this.emit = this.emit.bind(this)\n }\n\n toString(): string {\n return `${this.name}#${this.id.slice(-4)}`\n }\n\n scheduleMicrotask(fn: () => void): void {\n if (typeof queueMicrotask === 'function') {\n queueMicrotask(fn)\n return\n }\n void Promise.resolve().then(fn)\n }\n\n private async _runMiddlewareHook(hook: keyof EventBusMiddleware, args: unknown[]): Promise<void> {\n if (this.middlewares.length === 0) {\n return\n }\n for (const middleware of this.middlewares) {\n const callback = middleware[hook]\n if (!callback) {\n continue\n }\n await (callback as (...hook_args: unknown[]) => void | Promise<void>).apply(middleware, args)\n }\n }\n\n async onEventChange(event: BaseEvent, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._onEventChange(event, status)\n }\n\n async onEventResultChange(event: BaseEvent, result: EventResult, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._onEventResultChange(event, result, status)\n }\n\n private async _onEventChange(event: BaseEvent, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._runMiddlewareHook('onEventChange', [this, event, status])\n }\n\n private async _onEventResultChange(event: BaseEvent, result: EventResult, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._runMiddlewareHook('onEventResultChange', [this, event, result, status])\n }\n\n private async _onBusHandlersChange(handler: EventHandler, registered: boolean): Promise<void> {\n await this._runMiddlewareHook('onBusHandlersChange', [this, handler, registered])\n }\n\n private _finalizeEventTimeout(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n timeout_error: EventHandlerTimeoutError\n ): void {\n const timeout_seconds = timeout_error.timeout_seconds ?? event.event_timeout ?? null\n event._cancelPendingChildProcessing(timeout_error)\n\n for (const entry of pending_entries) {\n const result = entry.result\n if (result.status === 'completed') {\n continue\n }\n if (result.status === 'error') {\n continue\n }\n if (result.status === 'started') {\n result._lock?.exitHandlerRun()\n result._releaseQueueJumpPauses()\n const aborted_error = new EventHandlerAbortedError(`Aborted running handler due to event timeout`, {\n event_result: result,\n timeout_seconds,\n cause: timeout_error,\n })\n result._markError(aborted_error)\n result._signalAbort(aborted_error)\n continue\n }\n const cancelled_error = new EventHandlerCancelledError(`Cancelled pending handler due to event timeout`, {\n event_result: result,\n timeout_seconds,\n cause: timeout_error,\n })\n result._markError(cancelled_error)\n }\n\n event.event_pending_bus_count = Math.max(0, event.event_pending_bus_count - 1)\n event._markCompleted()\n }\n\n private _createEventTimeoutError(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n timeout_seconds: number\n ): EventHandlerTimeoutError {\n const timeout_anchor =\n pending_entries.find((entry) => entry.result.status === 'started') ??\n pending_entries.find((entry) => entry.result.status === 'pending') ??\n pending_entries[0]!\n return new EventHandlerTimeoutError(\n `${this.toString()}.on(${event.toString()}, ${timeout_anchor.result.handler.toString()}) timed out after ${timeout_seconds}s`,\n {\n event_result: timeout_anchor.result,\n timeout_seconds,\n }\n )\n }\n\n private async _runHandlersWithTimeout(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n event_timeout: number | null,\n fn: () => Promise<void>\n ): Promise<void> {\n try {\n if (event_timeout === null || pending_entries.length === 0) {\n await fn()\n } else {\n await _runWithTimeout(event_timeout, () => this._createEventTimeoutError(event, pending_entries, event_timeout), fn)\n }\n } catch (error) {\n if (error instanceof EventHandlerTimeoutError) {\n this._finalizeEventTimeout(event, pending_entries, error)\n return\n }\n throw error\n }\n }\n\n private _markEventCompletedIfNeeded(event: BaseEvent): void {\n if (event.event_status !== 'completed') {\n event.event_pending_bus_count = Math.max(0, event.event_pending_bus_count - 1)\n event._markCompleted(false)\n }\n if (\n this.event_history.max_history_size !== null &&\n this.event_history.max_history_size > 0 &&\n this.event_history.size > this.event_history.max_history_size\n ) {\n this.event_history.trimEventHistory({\n is_event_complete: (candidate_event) => candidate_event.event_status === 'completed',\n on_remove: (candidate_event) => candidate_event._gc(),\n owner_label: this.toString(),\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n })\n }\n }\n\n toJSON(): EventBusJSON {\n const handlers: Record<string, EventHandlerJSON> = {}\n for (const [handler_id, handler] of this.handlers.entries()) {\n handlers[handler_id] = handler.toJSON()\n }\n\n const handlers_by_key: Record<string, string[]> = {}\n for (const [key, ids] of this.handlers_by_key.entries()) {\n handlers_by_key[key] = [...ids]\n }\n\n const event_history: Record<string, BaseEventJSON> = {}\n for (const [event_id, event] of this.event_history.entries()) {\n event_history[event_id] = event.toJSON()\n }\n\n const pending_event_queue: string[] = []\n for (const event of this.pending_event_queue) {\n const event_id = event.event_id\n if (!event_history[event_id]) {\n event_history[event_id] = event.toJSON()\n }\n pending_event_queue.push(event_id)\n }\n\n return {\n id: this.id,\n name: this.name,\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n event_concurrency: this.event_concurrency,\n event_timeout: this.event_timeout,\n event_slow_timeout: this.event_slow_timeout,\n event_handler_concurrency: this.event_handler_concurrency,\n event_handler_completion: this.event_handler_completion,\n event_handler_slow_timeout: this.event_handler_slow_timeout,\n event_handler_detect_file_paths: this.event_handler_detect_file_paths,\n handlers,\n handlers_by_key,\n event_history,\n pending_event_queue,\n }\n }\n\n private static _stubHandlerFn(): EventHandlerCallable {\n return (() => undefined) as EventHandlerCallable\n }\n\n private static _upsertHandlerIndex(bus: EventBus, event_pattern: string, handler_id: string): void {\n const ids = bus.handlers_by_key.get(event_pattern)\n if (ids) {\n if (!ids.includes(handler_id)) {\n ids.push(handler_id)\n }\n return\n }\n bus.handlers_by_key.set(event_pattern, [handler_id])\n }\n\n private static _linkEventResultHandlers(event: BaseEvent, bus: EventBus): void {\n for (const [map_key, result] of Array.from(event.event_results.entries())) {\n const handler_id = result.handler_id\n const existing_handler = bus.handlers.get(handler_id)\n if (existing_handler) {\n result.handler = existing_handler\n } else {\n const source = result.handler\n const handler_entry = EventHandler.fromJSON(\n {\n ...source.toJSON(),\n id: handler_id,\n event_pattern: source.event_pattern || event.event_type,\n eventbus_name: source.eventbus_name || bus.name,\n eventbus_id: source.eventbus_id || bus.id,\n },\n EventBus._stubHandlerFn()\n )\n bus.handlers.set(handler_entry.id, handler_entry)\n EventBus._upsertHandlerIndex(bus, handler_entry.event_pattern, handler_entry.id)\n result.handler = handler_entry\n }\n\n if (map_key !== handler_id) {\n event.event_results.delete(map_key)\n event.event_results.set(handler_id, result)\n }\n }\n }\n\n static fromJSON(data: unknown): EventBus {\n if (!data || typeof data !== 'object') {\n throw new Error('EventBus.fromJSON(data) requires an object')\n }\n const record = data as Record<string, unknown>\n const name = typeof record.name === 'string' ? record.name : 'EventBus'\n const options: EventBusOptions = {}\n\n if (typeof record.id === 'string') options.id = record.id\n if (typeof record.max_history_size === 'number' || record.max_history_size === null) options.max_history_size = record.max_history_size\n if (typeof record.max_history_drop === 'boolean') options.max_history_drop = record.max_history_drop\n if (\n record.event_concurrency === 'global-serial' ||\n record.event_concurrency === 'bus-serial' ||\n record.event_concurrency === 'parallel'\n ) {\n options.event_concurrency = record.event_concurrency\n }\n if (typeof record.event_timeout === 'number' || record.event_timeout === null) options.event_timeout = record.event_timeout\n if (typeof record.event_slow_timeout === 'number' || record.event_slow_timeout === null)\n options.event_slow_timeout = record.event_slow_timeout\n if (record.event_handler_concurrency === 'serial' || record.event_handler_concurrency === 'parallel') {\n options.event_handler_concurrency = record.event_handler_concurrency\n }\n if (record.event_handler_completion === 'all' || record.event_handler_completion === 'first') {\n options.event_handler_completion = record.event_handler_completion\n }\n if (typeof record.event_handler_slow_timeout === 'number' || record.event_handler_slow_timeout === null) {\n options.event_handler_slow_timeout = record.event_handler_slow_timeout\n }\n if (typeof record.event_handler_detect_file_paths === 'boolean') {\n options.event_handler_detect_file_paths = record.event_handler_detect_file_paths\n }\n const bus = new EventBus(name, options)\n\n if (!record.handlers || typeof record.handlers !== 'object' || Array.isArray(record.handlers)) {\n throw new Error('EventBus.fromJSON(data) requires handlers as an id-keyed object')\n }\n for (const [handler_id, payload] of Object.entries(record.handlers as Record<string, unknown>)) {\n if (!payload || typeof payload !== 'object') {\n continue\n }\n const parsed = EventHandler.fromJSON(\n {\n ...(payload as Record<string, unknown>),\n id: typeof (payload as { id?: unknown }).id === 'string' ? (payload as { id: string }).id : handler_id,\n },\n EventBus._stubHandlerFn()\n )\n bus.handlers.set(parsed.id, parsed)\n }\n\n if (!record.handlers_by_key || typeof record.handlers_by_key !== 'object' || Array.isArray(record.handlers_by_key)) {\n throw new Error('EventBus.fromJSON(data) requires handlers_by_key as an object')\n }\n bus.handlers_by_key.clear()\n for (const [raw_key, raw_ids] of Object.entries(record.handlers_by_key as Record<string, unknown>)) {\n if (!Array.isArray(raw_ids)) {\n continue\n }\n const ids = raw_ids.filter((id): id is string => typeof id === 'string')\n bus.handlers_by_key.set(raw_key, ids)\n }\n\n if (!record.event_history || typeof record.event_history !== 'object' || Array.isArray(record.event_history)) {\n throw new Error('EventBus.fromJSON(data) requires event_history as an id-keyed object')\n }\n for (const [event_id, payload] of Object.entries(record.event_history as Record<string, unknown>)) {\n if (!payload || typeof payload !== 'object') {\n continue\n }\n const event = BaseEvent.fromJSON({\n ...(payload as Record<string, unknown>),\n event_id: typeof (payload as { event_id?: unknown }).event_id === 'string' ? (payload as { event_id: string }).event_id : event_id,\n })\n event.event_bus = bus\n bus.event_history.set(event.event_id, event)\n }\n\n if (!Array.isArray(record.pending_event_queue)) {\n throw new Error('EventBus.fromJSON(data) requires pending_event_queue as an array of event ids')\n }\n const raw_pending_event_queue = record.pending_event_queue\n const pending_event_ids: string[] = []\n for (const item of raw_pending_event_queue) {\n if (typeof item === 'string') {\n pending_event_ids.push(item)\n }\n }\n bus.pending_event_queue = pending_event_ids\n .map((event_id) => bus.event_history.get(event_id))\n .filter((event): event is BaseEvent => Boolean(event))\n\n for (const event of bus.event_history.values()) {\n EventBus._linkEventResultHandlers(event, bus)\n }\n\n // Reset runtime execution state after restore. Queue/history/handlers are restored,\n // but lock internals should always restart from a clean default state.\n bus.in_flight_event_ids.clear()\n bus.runloop_running = false\n bus.locks.clear()\n bus.find_waiters.clear()\n\n return bus\n }\n\n get label(): string {\n return `${this.name}#${this.id.slice(-4)}`\n }\n\n removeEventFromPendingQueue(event: BaseEvent): number {\n const original_event = event._event_original ?? event\n let removed_count = 0\n for (let index = this.pending_event_queue.length - 1; index >= 0; index -= 1) {\n const queued_event = this.pending_event_queue[index]\n const queued_original = queued_event._event_original ?? queued_event\n if (queued_original.event_id !== original_event.event_id) {\n continue\n }\n this.pending_event_queue.splice(index, 1)\n removed_count += 1\n }\n return removed_count\n }\n\n isEventInFlightOrQueued(event_id: string): boolean {\n if (this.in_flight_event_ids.has(event_id)) {\n return true\n }\n for (const queued_event of this.pending_event_queue) {\n const queued_original = queued_event._event_original ?? queued_event\n if (queued_original.event_id === event_id) {\n return true\n }\n }\n return false\n }\n\n removeEventFromHistory(event_id: string): boolean {\n return this.event_history.delete(event_id)\n }\n\n // destroy the event bus and all its state to allow for garbage collection\n destroy(): void {\n this.all_instances.discard(this)\n this.handlers.clear()\n this.handlers_by_key.clear()\n for (const event of this.event_history.values()) {\n event._gc()\n }\n this.event_history.clear()\n this.pending_event_queue.length = 0\n this.in_flight_event_ids.clear()\n this.find_waiters.clear()\n this.locks.clear()\n }\n\n on<T extends BaseEvent>(event_pattern: EventClass<T>, handler: EventHandlerCallable<T>, options?: Partial<EventHandler>): EventHandler\n on<T extends BaseEvent>(\n event_pattern: string | '*',\n handler: UntypedEventHandlerFunction<T>,\n options?: Partial<EventHandler>\n ): EventHandler\n on(\n event_pattern: EventPattern | '*',\n handler: EventHandlerCallable | UntypedEventHandlerFunction,\n options: Partial<EventHandler> = {}\n ): EventHandler {\n const normalized_key = normalizeEventPattern(event_pattern) // get string event_type or '*'\n const handler_name = EventHandler.handlerNameFromCallable(handler as EventHandlerCallable)\n const handler_entry = new EventHandler({\n handler: handler as EventHandlerCallable,\n handler_name,\n handler_registered_at: monotonicDatetime(),\n event_pattern: normalized_key,\n eventbus_name: this.name,\n eventbus_id: this.id,\n ...options,\n })\n if (this.event_handler_detect_file_paths) {\n // optionally perform (expensive) file path detection for the handler using Error().stack introspection\n // makes logs much more useful for debugging, but is expensive to do if not needed\n handler_entry._detectHandlerFilePath()\n }\n\n this.handlers.set(handler_entry.id, handler_entry)\n const ids = this.handlers_by_key.get(handler_entry.event_pattern)\n if (ids) ids.push(handler_entry.id)\n else this.handlers_by_key.set(handler_entry.event_pattern, [handler_entry.id])\n this.scheduleMicrotask(() => {\n void this._onBusHandlersChange(handler_entry, true)\n })\n return handler_entry\n }\n\n off<T extends BaseEvent>(event_pattern: EventPattern<T> | '*', handler?: EventHandlerCallable<T> | string | EventHandler): void {\n const normalized_key = normalizeEventPattern(event_pattern)\n if (typeof handler === 'object' && handler instanceof EventHandler && handler.id !== undefined) {\n handler = handler.id\n }\n const match_by_id = typeof handler === 'string'\n for (const entry of this.handlers.values()) {\n if (entry.event_pattern !== normalized_key) {\n continue\n }\n const handler_id = entry.id\n if (handler === undefined || (match_by_id ? handler_id === handler : entry.handler === (handler as EventHandlerCallable))) {\n this.handlers.delete(handler_id)\n this._removeIndexedHandler(entry.event_pattern, handler_id)\n this.scheduleMicrotask(() => {\n void this._onBusHandlersChange(entry, false)\n })\n }\n }\n }\n\n emit<T extends BaseEvent>(event: T): T {\n const original_event = event._event_original ?? event // if event is a bus-scoped proxy already, get the original underlying event object\n if (!original_event.event_bus) {\n // if we are the first bus to emit this event, set the event_bus property on the original event object\n original_event.event_bus = this\n }\n if (!Array.isArray(original_event.event_path)) {\n original_event.event_path = []\n }\n if (original_event._getDispatchContext() === undefined) {\n // when used in fastify/nextjs/other contexts with tracing based on AsyncLocalStorage in node\n // we want to capture the context at the emit site and use it when running handlers\n // because events may be handled async in a separate context than the emit site\n original_event._setDispatchContext(captureAsyncContext())\n }\n if (original_event.event_path.includes(this.label) || this._hasProcessedEvent(original_event)) {\n return this._getEventProxyScopedToThisBus(original_event) as T\n }\n\n if (!original_event.event_path.includes(this.label)) {\n original_event.event_path.push(this.label)\n }\n\n if (original_event.event_parent_id && original_event.event_emitted_by_handler_id) {\n const parent_result = original_event.event_parent?.event_results.get(original_event.event_emitted_by_handler_id)\n if (parent_result) {\n parent_result._linkEmittedChildEvent(original_event)\n }\n }\n\n if (\n this.event_history.max_history_size !== null &&\n this.event_history.max_history_size > 0 &&\n !this.event_history.max_history_drop &&\n this.event_history.size >= this.event_history.max_history_size\n ) {\n throw new Error(\n `${this.toString()}.emit(${original_event.event_type}) rejected: history limit reached (${this.event_history.size}/${this.event_history.max_history_size}); set event_history.max_history_drop=true to drop old history instead.`\n )\n }\n\n this.event_history.addEvent(original_event)\n this.event_history.trimEventHistory({\n is_event_complete: (candidate_event) => candidate_event.event_status === 'completed',\n on_remove: (candidate_event) => candidate_event._gc(),\n owner_label: this.toString(),\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n })\n this._resolveFindWaiters(original_event)\n\n original_event.event_pending_bus_count += 1\n this.pending_event_queue.push(original_event)\n this._startRunloop()\n\n return this._getEventProxyScopedToThisBus(original_event) as T\n }\n\n // alias for emit\n dispatch<T extends BaseEvent>(event: T): T {\n return this.emit(event)\n }\n\n // find a recent event or wait for a future event that matches some criteria\n find(event_pattern: '*', options?: FindOptions<BaseEvent>): Promise<BaseEvent | null>\n find(event_pattern: '*', where: (event: BaseEvent) => boolean, options?: FindOptions<BaseEvent>): Promise<BaseEvent | null>\n find<T extends BaseEvent>(event_pattern: EventPattern<T>, options?: FindOptions<T>): Promise<T | null>\n find<T extends BaseEvent>(event_pattern: EventPattern<T>, where: (event: T) => boolean, options?: FindOptions<T>): Promise<T | null>\n async find<T extends BaseEvent>(\n event_pattern: EventPattern<T> | '*',\n where_or_options: ((event: T) => boolean) | FindOptions<T> = {},\n maybe_options: FindOptions<T> = {}\n ): Promise<T | null> {\n const where = typeof where_or_options === 'function' ? where_or_options : () => true\n const options = typeof where_or_options === 'function' ? maybe_options : where_or_options\n // `limit` field-equality filter would collide with filter()'s cap arg; route it through `where`.\n let effective_where = where\n let effective_options: FindOptions<T> = options\n if (Object.prototype.hasOwnProperty.call(options, 'limit')) {\n const { limit: limit_field_value, ...rest } = options as FindOptions<T> & { limit: unknown }\n const inner_where = where\n effective_where = (event: T) => (event as unknown as Record<string, unknown>).limit === limit_field_value && inner_where(event)\n effective_options = rest as unknown as FindOptions<T>\n }\n const results = await this.filter(event_pattern as EventPattern<T> | '*', effective_where, { ...effective_options, limit: 1 })\n return results.length > 0 ? results[0] : null\n }\n\n // same as find() but returns the list of all matching events (newest to oldest)\n // optional `limit` arg caps the number of results returned\n filter(event_pattern: '*', options?: FilterOptions<BaseEvent>): Promise<BaseEvent[]>\n filter(event_pattern: '*', where: (event: BaseEvent) => boolean, options?: FilterOptions<BaseEvent>): Promise<BaseEvent[]>\n filter<T extends BaseEvent>(event_pattern: EventPattern<T>, options?: FilterOptions<T>): Promise<T[]>\n filter<T extends BaseEvent>(event_pattern: EventPattern<T>, where: (event: T) => boolean, options?: FilterOptions<T>): Promise<T[]>\n async filter<T extends BaseEvent>(\n event_pattern: EventPattern<T> | '*',\n where_or_options: ((event: T) => boolean) | FilterOptions<T> = {},\n maybe_options: FilterOptions<T> = {}\n ): Promise<T[]> {\n const where = typeof where_or_options === 'function' ? where_or_options : () => true\n const options = typeof where_or_options === 'function' ? maybe_options : where_or_options\n const matches = await this.event_history.filter(event_pattern as EventPattern<T> | '*', where, {\n ...options,\n event_is_child_of: (event, ancestor) => this.eventIsChildOf(event, ancestor),\n wait_for_future_match: (normalized_event_pattern, matches_fn, future) =>\n this._waitForFutureMatch(normalized_event_pattern, matches_fn, future),\n })\n return matches.map((match) => this._getEventProxyScopedToThisBus(match) as T)\n }\n\n private async _waitForFutureMatch(\n event_pattern: string | '*',\n matches: (event: BaseEvent) => boolean,\n future: boolean | number\n ): Promise<BaseEvent | null> {\n if (future === false) {\n return null\n }\n return await new Promise<BaseEvent | null>((resolve) => {\n const waiter: EphemeralFindEventHandler = {\n event_pattern,\n matches,\n resolve: (event) => resolve(event),\n }\n if (future !== true) {\n const timeout_ms = Math.max(0, Number(future)) * 1000\n waiter.timeout_id = setTimeout(() => {\n this.find_waiters.delete(waiter)\n resolve(null)\n }, timeout_ms)\n }\n this.find_waiters.add(waiter)\n })\n }\n\n async waitUntilIdle(timeout: number | null = null): Promise<boolean> {\n return await this.locks.waitForIdle(timeout)\n }\n\n // Weak idle check: only checks if handlers are idle, doesnt check that the queue is empty\n isIdle(): boolean {\n for (const event of this.event_history.values()) {\n for (const result of event.event_results.values()) {\n if (result.eventbus_id !== this.id) {\n continue\n }\n if (result.status === 'pending' || result.status === 'started') {\n return false\n }\n }\n }\n return true // no handlers are pending or started\n }\n\n // Stronger idle check: no queued work, no in-flight processing, _runloop not\n // active, and no handlers pending/running for this bus.\n isIdleAndQueueEmpty(): boolean {\n return this.pending_event_queue.length === 0 && this.in_flight_event_ids.size === 0 && this.isIdle() && !this.runloop_running\n }\n\n eventIsChildOf(child_event: BaseEvent, parent_event: BaseEvent): boolean {\n if (child_event.event_id === parent_event.event_id) {\n return false\n }\n\n let current_parent_id = child_event.event_parent_id\n while (current_parent_id) {\n if (current_parent_id === parent_event.event_id) {\n return true\n }\n const parent = this.event_history.get(current_parent_id)\n if (!parent) {\n return false\n }\n current_parent_id = parent.event_parent_id\n }\n return false\n }\n\n eventIsParentOf(parent_event: BaseEvent, child_event: BaseEvent): boolean {\n return this.eventIsChildOf(child_event, parent_event)\n }\n\n // return a full detailed tree diagram of all events and results on this bus\n logTree(): string {\n return logTree(this)\n }\n\n // Resolve an event id from this bus first, then across all known buses.\n findEventById(event_id: string): BaseEvent | null {\n return this.event_history.get(event_id) ?? this.all_instances.findEventById(event_id)\n }\n\n private _startRunloop(): void {\n if (this.runloop_running) {\n return\n }\n this.runloop_running = true\n this.scheduleMicrotask(() => {\n void this._runloop()\n })\n }\n\n // schedule the processing of an event on the event bus by its normal _runloop\n // optionally using a pre-acquired lock if we're inside handling of a parent event\n private async _processEvent(\n event: BaseEvent,\n options: {\n bypass_event_locks?: boolean\n pre_acquired_lock?: AsyncLock | null\n } = {}\n ): Promise<void> {\n let pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }> = []\n try {\n if (this._hasProcessedEvent(event)) {\n return\n }\n const scoped_event = this._getEventProxyScopedToThisBus(event)\n await this._onEventChange(scoped_event, 'pending')\n event._markStarted()\n pending_entries = event._createPendingHandlerResults(this)\n const resolved_event_timeout = event.event_timeout ?? this.event_timeout\n if (this.middlewares.length > 0) {\n for (const entry of pending_entries) {\n await this._onEventResultChange(scoped_event, entry.result, 'pending')\n }\n }\n await this.locks._runWithEventLock(\n event,\n () =>\n this._runHandlersWithTimeout(event, pending_entries, resolved_event_timeout, () =>\n _runWithSlowMonitor(event._createSlowEventWarningTimer(), () => scoped_event._runHandlers(pending_entries))\n ),\n options\n )\n this._markEventCompletedIfNeeded(event)\n } finally {\n if (options.pre_acquired_lock) {\n options.pre_acquired_lock.release()\n }\n this.in_flight_event_ids.delete(event.event_id)\n this.locks._notifyIdleListeners()\n }\n }\n\n // Called when a handler does `await child.done()` \u2014 processes the child event\n // immediately (\"queue-jump\") instead of waiting for the _runloop to pick it up.\n //\n // Yield-and-reacquire: if the calling handler holds a handler concurrency lock,\n // we temporarily release it so child handlers on the same bus can acquire it\n // (preventing deadlock for serial handler mode). We re-acquire after\n // the child completes so the parent handler can continue with the lock held.\n async _processEventImmediately<T extends BaseEvent>(event: T, handler_result?: EventResult): Promise<T> {\n const original_event = event._event_original ?? event\n // Find the handler result for the current await call site. Proxy-provided\n // context covers event.emit(...); async-local context lets awaited bus.emit(...)\n // events queue-jump without implicitly changing their parentage.\n const proxy_result = handler_result?.status === 'started' ? handler_result : undefined\n const currently_active_event_result = proxy_result ?? this.locks._getActiveHandlerResultForCurrentAsyncContext()\n if (!currently_active_event_result) {\n // Not inside any handler scope \u2014 avoid queue-jump, but if this event is\n // next in line we can process it immediately without waiting on the _runloop.\n // We must acquire/revalidate the event lock first to avoid racing the runloop\n // and accidentally reordering/removing the wrong queue head.\n const queue_index = this.pending_event_queue.indexOf(original_event)\n const can_process_now =\n queue_index === 0 &&\n !this.locks._isPaused() &&\n !this.in_flight_event_ids.has(original_event.event_id) &&\n !this._hasProcessedEvent(original_event)\n if (can_process_now) {\n const event_lock = this.locks.getLockForEvent(original_event)\n let pre_acquired_lock: AsyncLock | null = null\n if (event_lock) {\n await event_lock.acquire()\n pre_acquired_lock = event_lock\n }\n const queue_head = this.pending_event_queue[0]\n const queue_head_original = queue_head?._event_original ?? queue_head\n const still_can_process_now =\n queue_head_original === original_event &&\n !this.locks._isPaused() &&\n !this.in_flight_event_ids.has(original_event.event_id) &&\n !this._hasProcessedEvent(original_event)\n if (still_can_process_now) {\n this.pending_event_queue.shift()\n this.in_flight_event_ids.add(original_event.event_id)\n await this._processEvent(original_event, {\n bypass_event_locks: true,\n pre_acquired_lock,\n })\n if (original_event.event_status !== 'completed') {\n await original_event.eventCompleted()\n }\n return event\n }\n if (pre_acquired_lock) {\n pre_acquired_lock.release()\n }\n }\n await original_event.eventCompleted()\n return event\n }\n\n const active_parent = currently_active_event_result.event._event_original ?? currently_active_event_result.event\n const is_child_of_active_handler =\n original_event.event_parent_id === active_parent.event_id &&\n original_event.event_emitted_by_handler_id === currently_active_event_result.handler_id &&\n currently_active_event_result.event_children.some((child) => (child._event_original ?? child).event_id === original_event.event_id)\n if (is_child_of_active_handler) {\n original_event.event_blocks_parent_completion = true\n }\n\n // Serial event modes need the runloop paused while the queue-jumped child\n // runs so queued siblings cannot overshoot the suspended parent handler.\n // Parallel events have no event lock, so pausing here would incorrectly\n // block later parallel work emitted by the same parent.\n if (this.locks.getLockForEvent(original_event) !== null) {\n currently_active_event_result._ensureQueueJumpPause(this)\n }\n if (original_event.event_status === 'completed') {\n return event\n }\n\n // re-endter event-level handler lock if needed\n if (currently_active_event_result._lock) {\n await currently_active_event_result._lock.runQueueJump(this._processEventImmediatelyAcrossBuses.bind(this, original_event))\n return event\n }\n\n await this._processEventImmediatelyAcrossBuses(original_event)\n return event\n }\n\n // Processes a queue-jumped event across all buses that have it emitted.\n // Called from _processEventImmediately after the parent handler's lock has been yielded.\n private async _processEventImmediatelyAcrossBuses(event: BaseEvent): Promise<void> {\n // Use event_path ordering to pick candidate buses and filter out buses that\n // haven't seen the event or already processed it.\n const ordered: EventBus[] = []\n const seen = new Set<EventBus>()\n const event_path = Array.isArray(event.event_path) ? event.event_path : []\n for (const label of event_path) {\n for (const bus of this.all_instances) {\n if (bus.label !== label) {\n continue\n }\n if (!bus.event_history.has(event.event_id)) {\n continue\n }\n if (bus._hasProcessedEvent(event)) {\n continue\n }\n if (!seen.has(bus)) {\n ordered.push(bus)\n seen.add(bus)\n }\n }\n }\n if (!seen.has(this) && this.event_history.has(event.event_id)) {\n ordered.push(this)\n }\n if (ordered.length === 0) {\n await event.eventCompleted()\n return\n }\n\n // Determine which event lock the initiating bus resolves to, so we can\n // detect when other buses share the same instance (global-serial).\n const initiating_event_lock = this.locks.getLockForEvent(event)\n const pause_releases: Array<() => void> = []\n\n try {\n for (const bus of ordered) {\n if (bus !== this) {\n pause_releases.push(bus.locks._requestRunloopPause())\n }\n }\n\n for (const bus of ordered) {\n const index = bus.pending_event_queue.indexOf(event)\n if (index >= 0) {\n bus.pending_event_queue.splice(index, 1)\n }\n if (bus._hasProcessedEvent(event)) {\n continue\n }\n if (bus.in_flight_event_ids.has(event.event_id)) {\n continue\n }\n bus.in_flight_event_ids.add(event.event_id)\n\n // Bypass event lock on the initiating bus (we're already inside a handler\n // that acquired it). For other buses, only bypass if they resolve to the same\n // lock instance (global-serial shares one lock across all buses).\n const bus_event_lock = bus.locks.getLockForEvent(event)\n const should_bypass_event_lock = bus === this || (initiating_event_lock !== null && bus_event_lock === initiating_event_lock)\n\n await bus._processEvent(event, {\n bypass_event_locks: should_bypass_event_lock,\n })\n }\n\n if (event.event_status !== 'completed') {\n await event.eventCompleted()\n }\n } finally {\n for (const release of pause_releases) {\n release()\n }\n }\n }\n\n private async _runloop(): Promise<void> {\n for (;;) {\n while (this.pending_event_queue.length > 0) {\n await Promise.resolve()\n if (this.locks._isPaused()) {\n await this.locks._waitUntilRunloopResumed()\n continue\n }\n const next_event = this.pending_event_queue[0]\n if (!next_event) {\n continue\n }\n const original_event = next_event._event_original ?? next_event\n if (this._hasProcessedEvent(original_event)) {\n this.pending_event_queue.shift()\n continue\n }\n let pre_acquired_lock: AsyncLock | null = null\n const event_lock = this.locks.getLockForEvent(original_event)\n if (event_lock) {\n await event_lock.acquire()\n pre_acquired_lock = event_lock\n }\n // Queue head may have changed while waiting for the lock\n // (e.g. done() processing the head immediately). Revalidate\n // before mutating the queue to avoid removing the wrong event.\n const current_head = this.pending_event_queue[0]\n const current_head_original = current_head?._event_original ?? current_head\n if (current_head_original !== original_event) {\n if (pre_acquired_lock) {\n pre_acquired_lock.release()\n }\n continue\n }\n this.pending_event_queue.shift()\n if (this.in_flight_event_ids.has(original_event.event_id)) {\n if (pre_acquired_lock) {\n pre_acquired_lock.release()\n }\n continue\n }\n this.in_flight_event_ids.add(original_event.event_id)\n void this._processEvent(original_event, {\n bypass_event_locks: true,\n pre_acquired_lock,\n })\n await Promise.resolve()\n }\n this.runloop_running = false\n if (this.pending_event_queue.length > 0) {\n this._startRunloop()\n return\n }\n this.locks._notifyIdleListeners()\n return\n }\n }\n\n // check if an event has been processed (and completed) by this bus\n _hasProcessedEvent(event: BaseEvent): boolean {\n const results = Array.from(event.event_results.values()).filter((result) => result.eventbus_id === this.id)\n if (results.length === 0) {\n return false\n }\n return results.every((result) => result.status === 'completed' || result.status === 'error')\n }\n\n // get a proxy wrapper around an Event that will automatically link emitted child events to this bus and handler\n // proxy is what gets passed into the handler, if handler does event.emit(...) to dispatch child events,\n // the proxy auto-sets event.parent_event_id and event.event_emitted_by_handler_id\n _getEventProxyScopedToThisBus<T extends BaseEvent>(event: T, handler_result?: EventResult): T {\n const original_event = event._event_original ?? event\n const bus = this\n const parent_event_id = original_event.event_id\n const bus_proxy = new Proxy(bus, {\n get(target, prop, receiver) {\n if (prop === '_processEventImmediately') {\n const runner = Reflect.get(target, prop, receiver) as EventBus['_processEventImmediately']\n const process_event_immediately = <TChild extends BaseEvent>(child_event: TChild): Promise<TChild> => {\n return runner.call(target, child_event, handler_result) as Promise<TChild>\n }\n return process_event_immediately\n }\n if (prop === 'dispatch' || prop === 'emit') {\n const emit_child_event = <TChild extends BaseEvent>(child_event: TChild): TChild => {\n const original_child = child_event._event_original ?? child_event\n if (handler_result) {\n handler_result._linkEmittedChildEvent(original_child)\n } else if (!original_child.event_parent_id && original_child.event_id !== parent_event_id) {\n // fallback for non-handler scoped emit/dispatch\n original_child.event_parent_id = parent_event_id\n }\n const dispatcher = Reflect.get(target, prop, receiver) as EventBus['dispatch']\n const dispatched = dispatcher.call(target, original_child)\n return target._getEventProxyScopedToThisBus(dispatched as TChild, handler_result)\n }\n return emit_child_event\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n const scoped = new Proxy(original_event, {\n get(target, prop, receiver) {\n if (prop === 'event_bus') {\n return bus_proxy\n }\n if (prop === '_event_original') {\n return target\n }\n return Reflect.get(target, prop, receiver)\n },\n set(target, prop, value) {\n if (prop === 'event_bus') {\n return true\n }\n return Reflect.set(target, prop, value, target)\n },\n has(target, prop) {\n if (prop === 'event_bus') {\n return true\n }\n if (prop === '_event_original') {\n return true\n }\n return Reflect.has(target, prop)\n },\n })\n\n return scoped as T\n }\n\n private _resolveFindWaiters(event: BaseEvent): void {\n for (const waiter of Array.from(this.find_waiters)) {\n if ((waiter.event_pattern !== '*' && event.event_type !== waiter.event_pattern) || !waiter.matches(event)) {\n continue\n }\n if (waiter.timeout_id) {\n clearTimeout(waiter.timeout_id)\n }\n this.find_waiters.delete(waiter)\n waiter.resolve(event)\n }\n }\n\n _getHandlersForEvent(event: BaseEvent): EventHandler[] {\n const handlers: EventHandler[] = []\n for (const key of [event.event_type, '*']) {\n const ids = this.handlers_by_key.get(key)\n if (!ids) continue\n for (const id of ids) {\n const entry = this.handlers.get(id)\n if (entry) handlers.push(entry)\n }\n }\n return handlers\n }\n\n private _removeIndexedHandler(event_pattern: string | '*', handler_id: string): void {\n const ids = this.handlers_by_key.get(event_pattern)\n if (!ids) return\n const idx = ids.indexOf(handler_id)\n if (idx < 0) return\n ids.splice(idx, 1)\n if (ids.length === 0) this.handlers_by_key.delete(event_pattern)\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { BaseEvent, type BaseEventJSON } from './BaseEvent.js'\nimport { EventHistory } from './EventHistory.js'\nimport { EventResult } from './EventResult.js'\nimport { captureAsyncContext } from './async_context.js'\nimport { _runWithSlowMonitor, _runWithTimeout } from './timing.js'\nimport {\n AsyncLock,\n type EventConcurrencyMode,\n type EventHandlerConcurrencyMode,\n type EventHandlerCompletionMode,\n LockManager,\n} from './LockManager.js'\nimport {\n EventHandler,\n EventHandlerAbortedError,\n EventHandlerCancelledError,\n EventHandlerTimeoutError,\n type EphemeralFindEventHandler,\n type EventHandlerJSON,\n} from './EventHandler.js'\nimport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './EventBusMiddleware.js'\nimport { logTree } from './logging.js'\nimport { v7 as uuidv7 } from 'uuid'\nimport { monotonicDatetime } from './helpers.js'\n\nimport { normalizeEventPattern } from './types.js'\nimport type { EventClass, EventHandlerCallable, EventPattern, FilterOptions, FindOptions, UntypedEventHandlerFunction } from './types.js'\n\nexport type EventBusOptions = {\n id?: string\n max_history_size?: number | null\n max_history_drop?: boolean\n\n // per-event options\n event_concurrency?: EventConcurrencyMode | null\n event_timeout?: number | null // default handler timeout in seconds, applied when event.event_timeout is undefined\n event_slow_timeout?: number | null // threshold before a warning is logged about slow event processing\n\n // per-event-handler options\n event_handler_concurrency?: EventHandlerConcurrencyMode | null\n event_handler_completion?: EventHandlerCompletionMode\n event_handler_slow_timeout?: number | null // threshold before a warning is logged about slow handler execution\n event_handler_detect_file_paths?: boolean // autodetect source code file and lineno where handlers are defined for better logs (slightly slower because Error().stack introspection to fine files is expensive)\n middlewares?: EventBusMiddlewareInput[]\n}\n\nexport type EventBusDestroyOptions = {\n clear?: boolean\n}\n\nexport type EventBusJSON = {\n id: string\n name: string\n max_history_size: number | null\n max_history_drop: boolean\n event_concurrency: EventConcurrencyMode\n event_timeout: number | null\n event_slow_timeout: number | null\n event_handler_concurrency: EventHandlerConcurrencyMode\n event_handler_completion: EventHandlerCompletionMode\n event_handler_slow_timeout: number | null\n event_handler_detect_file_paths: boolean\n handlers: Record<string, EventHandlerJSON>\n handlers_by_key: Record<string, string[]>\n event_history: Record<string, BaseEventJSON>\n pending_event_queue: string[]\n}\n\n// Global registry of all EventBus instances to allow for cross-bus coordination\n// when global-serial concurrency mode is used.\nexport class GlobalEventBusRegistry {\n private _bus_refs = new Set<WeakRef<EventBus>>()\n\n add(bus: EventBus): void {\n this._bus_refs.add(new WeakRef(bus))\n }\n\n discard(bus: EventBus): void {\n for (const ref of this._bus_refs) {\n const current = ref.deref()\n if (!current || current === bus) {\n this._bus_refs.delete(ref)\n }\n }\n }\n\n has(bus: EventBus): boolean {\n for (const ref of this._bus_refs) {\n const current = ref.deref()\n if (!current) {\n this._bus_refs.delete(ref)\n continue\n }\n if (current === bus) {\n return true\n }\n }\n return false\n }\n\n get size(): number {\n let count = 0\n for (const ref of this._bus_refs) {\n if (ref.deref()) {\n count += 1\n } else {\n this._bus_refs.delete(ref)\n }\n }\n return count\n }\n\n *[Symbol.iterator](): IterableIterator<EventBus> {\n for (const ref of this._bus_refs) {\n const bus = ref.deref()\n if (bus) {\n yield bus\n } else {\n this._bus_refs.delete(ref)\n }\n }\n }\n\n findBusById(bus_id: string): EventBus | undefined {\n for (const bus of this) {\n if (bus.id === bus_id) {\n return bus\n }\n }\n return undefined\n }\n\n findEventById(event_id: string): BaseEvent | null {\n for (const bus of this) {\n const event = bus.event_history.getEvent(event_id)\n if (event) {\n return event\n }\n }\n return null\n }\n}\n\nexport class EventBus {\n private static _registry_by_constructor = new WeakMap<Function, GlobalEventBusRegistry>()\n private static _global_event_lock_by_constructor = new WeakMap<Function, AsyncLock>()\n\n private static getRegistryForConstructor(constructor_fn: Function): GlobalEventBusRegistry {\n const existing_registry = EventBus._registry_by_constructor.get(constructor_fn)\n if (existing_registry) {\n return existing_registry\n }\n const created_registry = new GlobalEventBusRegistry()\n EventBus._registry_by_constructor.set(constructor_fn, created_registry)\n return created_registry\n }\n\n private static getGlobalEventLockForConstructor(constructor_fn: Function): AsyncLock {\n const existing_lock = EventBus._global_event_lock_by_constructor.get(constructor_fn)\n if (existing_lock) {\n return existing_lock\n }\n const created_lock = new AsyncLock(1)\n EventBus._global_event_lock_by_constructor.set(constructor_fn, created_lock)\n return created_lock\n }\n\n static get all_instances(): GlobalEventBusRegistry {\n return EventBus.getRegistryForConstructor(this)\n }\n\n get all_instances(): GlobalEventBusRegistry {\n return EventBus.getRegistryForConstructor(this.constructor as Function)\n }\n\n get _lock_for_event_global_serial(): AsyncLock {\n return EventBus.getGlobalEventLockForConstructor(this.constructor as Function)\n }\n\n id: string // unique uuidv7 identifier for the event bus\n name: string // name of the event bus, recommended to include the word \"Bus\" in the name for clarity in logs\n\n // configuration options\n event_timeout: number | null\n event_concurrency: EventConcurrencyMode\n event_handler_concurrency: EventHandlerConcurrencyMode\n event_handler_completion: EventHandlerCompletionMode\n event_handler_detect_file_paths: boolean\n\n // slow processing warning timeout settings\n event_handler_slow_timeout: number | null\n event_slow_timeout: number | null\n\n // public runtime state\n handlers: Map<string, EventHandler> // map of handler uuidv5 ids to EventHandler objects\n handlers_by_key: Map<string, string[]> // map of normalized event_pattern to ordered handler ids\n event_history: EventHistory<BaseEvent> // map of event uuidv7 ids to processed BaseEvent objects\n\n // internal runtime state\n pending_event_queue: BaseEvent[] // queue of events that have been emitted to the bus but not yet processed\n in_flight_event_ids: Set<string> // set of event ids that are currently being processed by the bus\n runloop_running: boolean\n locks: LockManager\n find_waiters: Set<EphemeralFindEventHandler> // set of EphemeralFindEventHandler objects that are waiting for a matching future event\n middlewares: EventBusMiddleware[]\n private destroyed: boolean\n\n private static normalizeMiddlewares(middlewares?: EventBusMiddlewareInput[]): EventBusMiddleware[] {\n const normalized: EventBusMiddleware[] = []\n for (const middleware of middlewares ?? []) {\n if (!middleware) {\n continue\n }\n if (typeof middleware === 'function') {\n normalized.push(new (middleware as EventBusMiddlewareCtor)())\n } else {\n normalized.push(middleware as EventBusMiddleware)\n }\n }\n return normalized\n }\n\n constructor(name: string = 'EventBus', options: EventBusOptions = {}) {\n this.id = options.id ?? uuidv7()\n this.name = name\n\n // set configuration options\n this.event_concurrency = options.event_concurrency ?? 'bus-serial'\n this.event_handler_concurrency = options.event_handler_concurrency ?? 'serial'\n this.event_handler_completion = options.event_handler_completion ?? 'all'\n this.event_handler_detect_file_paths = options.event_handler_detect_file_paths ?? true\n this.event_timeout = options.event_timeout ?? 60\n this.event_handler_slow_timeout = options.event_handler_slow_timeout ?? 30\n this.event_slow_timeout = options.event_slow_timeout ?? 300\n\n // initialize runtime state\n this.runloop_running = false\n this.handlers = new Map()\n this.handlers_by_key = new Map()\n this.find_waiters = new Set()\n this.event_history = new EventHistory({\n max_history_size: options.max_history_size === undefined ? 100 : options.max_history_size,\n max_history_drop: options.max_history_drop ?? false,\n })\n this.pending_event_queue = []\n this.in_flight_event_ids = new Set()\n this.locks = new LockManager(this)\n this.middlewares = EventBus.normalizeMiddlewares(options.middlewares)\n this.destroyed = false\n\n this.all_instances.add(this)\n\n this.dispatch = this.dispatch.bind(this)\n this.emit = this.emit.bind(this)\n }\n\n toString(): string {\n return `${this.name}#${this.id.slice(-4)}`\n }\n\n scheduleMicrotask(fn: () => void): void {\n if (typeof queueMicrotask === 'function') {\n queueMicrotask(fn)\n return\n }\n void Promise.resolve().then(fn)\n }\n\n private async _runMiddlewareHook(hook: keyof EventBusMiddleware, args: unknown[]): Promise<void> {\n if (this.middlewares.length === 0) {\n return\n }\n for (const middleware of this.middlewares) {\n const callback = middleware[hook]\n if (!callback) {\n continue\n }\n await (callback as (...hook_args: unknown[]) => void | Promise<void>).apply(middleware, args)\n }\n }\n\n async onEventChange(event: BaseEvent, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._onEventChange(event, status)\n }\n\n async onEventResultChange(event: BaseEvent, result: EventResult, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._onEventResultChange(event, result, status)\n }\n\n private async _onEventChange(event: BaseEvent, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._runMiddlewareHook('onEventChange', [this, event, status])\n }\n\n private async _onEventResultChange(event: BaseEvent, result: EventResult, status: 'pending' | 'started' | 'completed'): Promise<void> {\n await this._runMiddlewareHook('onEventResultChange', [this, event, result, status])\n }\n\n private async _onBusHandlersChange(handler: EventHandler, registered: boolean): Promise<void> {\n await this._runMiddlewareHook('onBusHandlersChange', [this, handler, registered])\n }\n\n private _finalizeEventTimeout(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n timeout_error: EventHandlerTimeoutError\n ): void {\n const timeout_seconds = timeout_error.timeout_seconds ?? event.event_timeout ?? null\n event._cancelPendingChildProcessing(timeout_error)\n\n for (const entry of pending_entries) {\n const result = entry.result\n if (result.status === 'completed') {\n continue\n }\n if (result.status === 'error') {\n continue\n }\n if (result.status === 'started') {\n result._lock?.exitHandlerRun()\n result._releaseQueueJumpPauses()\n const aborted_error = new EventHandlerAbortedError(`Aborted running handler due to event timeout`, {\n event_result: result,\n timeout_seconds,\n cause: timeout_error,\n })\n result._markError(aborted_error)\n result._signalAbort(aborted_error)\n continue\n }\n const cancelled_error = new EventHandlerCancelledError(`Cancelled pending handler due to event timeout`, {\n event_result: result,\n timeout_seconds,\n cause: timeout_error,\n })\n result._markError(cancelled_error)\n }\n\n event.event_pending_bus_count = Math.max(0, event.event_pending_bus_count - 1)\n event._markCompleted()\n }\n\n private _createEventTimeoutError(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n timeout_seconds: number\n ): EventHandlerTimeoutError {\n const timeout_anchor =\n pending_entries.find((entry) => entry.result.status === 'started') ??\n pending_entries.find((entry) => entry.result.status === 'pending') ??\n pending_entries[0]!\n return new EventHandlerTimeoutError(\n `${this.toString()}.on(${event.toString()}, ${timeout_anchor.result.handler.toString()}) timed out after ${timeout_seconds}s`,\n {\n event_result: timeout_anchor.result,\n timeout_seconds,\n }\n )\n }\n\n private async _runHandlersWithTimeout(\n event: BaseEvent,\n pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }>,\n event_timeout: number | null,\n fn: () => Promise<void>\n ): Promise<void> {\n try {\n if (event_timeout === null || event_timeout <= 0 || pending_entries.length === 0) {\n await fn()\n } else {\n await _runWithTimeout(event_timeout, () => this._createEventTimeoutError(event, pending_entries, event_timeout), fn)\n }\n } catch (error) {\n if (error instanceof EventHandlerTimeoutError) {\n this._finalizeEventTimeout(event, pending_entries, error)\n return\n }\n throw error\n }\n }\n\n private _markEventCompletedIfNeeded(event: BaseEvent): void {\n if (event.event_status !== 'completed') {\n event.event_pending_bus_count = Math.max(0, event.event_pending_bus_count - 1)\n event._markCompleted(false)\n }\n if (\n this.event_history.max_history_size !== null &&\n this.event_history.max_history_size > 0 &&\n this.event_history.size > this.event_history.max_history_size\n ) {\n this.event_history.trimEventHistory({\n is_event_complete: (candidate_event) => candidate_event.event_status === 'completed',\n on_remove: (candidate_event) => candidate_event._gc(),\n owner_label: this.toString(),\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n })\n }\n }\n\n toJSON(): EventBusJSON {\n const handlers: Record<string, EventHandlerJSON> = {}\n for (const [handler_id, handler] of this.handlers.entries()) {\n handlers[handler_id] = handler.toJSON()\n }\n\n const handlers_by_key: Record<string, string[]> = {}\n for (const [key, ids] of this.handlers_by_key.entries()) {\n handlers_by_key[key] = [...ids]\n }\n\n const event_history: Record<string, BaseEventJSON> = {}\n for (const [event_id, event] of this.event_history.entries()) {\n event_history[event_id] = event.toJSON()\n }\n\n const pending_event_queue: string[] = []\n for (const event of this.pending_event_queue) {\n const event_id = event.event_id\n if (!event_history[event_id]) {\n event_history[event_id] = event.toJSON()\n }\n pending_event_queue.push(event_id)\n }\n\n return {\n id: this.id,\n name: this.name,\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n event_concurrency: this.event_concurrency,\n event_timeout: this.event_timeout,\n event_slow_timeout: this.event_slow_timeout,\n event_handler_concurrency: this.event_handler_concurrency,\n event_handler_completion: this.event_handler_completion,\n event_handler_slow_timeout: this.event_handler_slow_timeout,\n event_handler_detect_file_paths: this.event_handler_detect_file_paths,\n handlers,\n handlers_by_key,\n event_history,\n pending_event_queue,\n }\n }\n\n private static _stubHandlerFn(): EventHandlerCallable {\n return (() => undefined) as EventHandlerCallable\n }\n\n private static _upsertHandlerIndex(bus: EventBus, event_pattern: string, handler_id: string): void {\n const ids = bus.handlers_by_key.get(event_pattern)\n if (ids) {\n if (!ids.includes(handler_id)) {\n ids.push(handler_id)\n }\n return\n }\n bus.handlers_by_key.set(event_pattern, [handler_id])\n }\n\n private static _linkEventResultHandlers(event: BaseEvent, bus: EventBus): void {\n for (const [map_key, result] of Array.from(event.event_results.entries())) {\n const handler_id = result.handler_id\n const existing_handler = bus.handlers.get(handler_id)\n if (existing_handler) {\n result.handler = existing_handler\n } else {\n const source = result.handler\n const handler_entry = EventHandler.fromJSON(\n {\n ...source.toJSON(),\n id: handler_id,\n event_pattern: source.event_pattern || event.event_type,\n eventbus_name: source.eventbus_name || bus.name,\n eventbus_id: source.eventbus_id || bus.id,\n },\n EventBus._stubHandlerFn()\n )\n bus.handlers.set(handler_entry.id, handler_entry)\n EventBus._upsertHandlerIndex(bus, handler_entry.event_pattern, handler_entry.id)\n result.handler = handler_entry\n }\n\n if (map_key !== handler_id) {\n event.event_results.delete(map_key)\n event.event_results.set(handler_id, result)\n }\n }\n }\n\n static fromJSON(data: unknown): EventBus {\n if (!data || typeof data !== 'object') {\n throw new Error('EventBus.fromJSON(data) requires an object')\n }\n const record = data as Record<string, unknown>\n const name = typeof record.name === 'string' ? record.name : 'EventBus'\n const options: EventBusOptions = {}\n\n if (typeof record.id === 'string') options.id = record.id\n if (typeof record.max_history_size === 'number' || record.max_history_size === null) options.max_history_size = record.max_history_size\n if (typeof record.max_history_drop === 'boolean') options.max_history_drop = record.max_history_drop\n if (\n record.event_concurrency === 'global-serial' ||\n record.event_concurrency === 'bus-serial' ||\n record.event_concurrency === 'parallel'\n ) {\n options.event_concurrency = record.event_concurrency\n }\n if (typeof record.event_timeout === 'number' || record.event_timeout === null) options.event_timeout = record.event_timeout\n if (typeof record.event_slow_timeout === 'number' || record.event_slow_timeout === null)\n options.event_slow_timeout = record.event_slow_timeout\n if (record.event_handler_concurrency === 'serial' || record.event_handler_concurrency === 'parallel') {\n options.event_handler_concurrency = record.event_handler_concurrency\n }\n if (record.event_handler_completion === 'all' || record.event_handler_completion === 'first') {\n options.event_handler_completion = record.event_handler_completion\n }\n if (typeof record.event_handler_slow_timeout === 'number' || record.event_handler_slow_timeout === null) {\n options.event_handler_slow_timeout = record.event_handler_slow_timeout\n }\n if (typeof record.event_handler_detect_file_paths === 'boolean') {\n options.event_handler_detect_file_paths = record.event_handler_detect_file_paths\n }\n const bus = new EventBus(name, options)\n\n const raw_handlers = record.handlers ?? {}\n if (!raw_handlers || typeof raw_handlers !== 'object' || Array.isArray(raw_handlers)) {\n throw new Error('EventBus.fromJSON(data) requires handlers as an id-keyed object')\n }\n for (const [handler_id, payload] of Object.entries(raw_handlers as Record<string, unknown>)) {\n if (!payload || typeof payload !== 'object') {\n continue\n }\n const parsed = EventHandler.fromJSON(\n {\n ...(payload as Record<string, unknown>),\n id: typeof (payload as { id?: unknown }).id === 'string' ? (payload as { id: string }).id : handler_id,\n },\n EventBus._stubHandlerFn()\n )\n bus.handlers.set(parsed.id, parsed)\n }\n\n const raw_handlers_by_key = record.handlers_by_key ?? {}\n if (!raw_handlers_by_key || typeof raw_handlers_by_key !== 'object' || Array.isArray(raw_handlers_by_key)) {\n throw new Error('EventBus.fromJSON(data) requires handlers_by_key as an object')\n }\n bus.handlers_by_key.clear()\n for (const [raw_key, raw_ids] of Object.entries(raw_handlers_by_key as Record<string, unknown>)) {\n if (!Array.isArray(raw_ids)) {\n continue\n }\n const ids = raw_ids.filter((id): id is string => typeof id === 'string')\n bus.handlers_by_key.set(raw_key, ids)\n }\n\n if (!record.event_history || typeof record.event_history !== 'object' || Array.isArray(record.event_history)) {\n throw new Error('EventBus.fromJSON(data) requires event_history as an id-keyed object')\n }\n for (const [event_id, payload] of Object.entries(record.event_history as Record<string, unknown>)) {\n if (!payload || typeof payload !== 'object') {\n continue\n }\n const event = BaseEvent.fromJSON({\n ...(payload as Record<string, unknown>),\n event_id: typeof (payload as { event_id?: unknown }).event_id === 'string' ? (payload as { event_id: string }).event_id : event_id,\n })\n event.event_bus = bus\n bus.event_history.set(event.event_id, event)\n }\n\n if (!Array.isArray(record.pending_event_queue)) {\n throw new Error('EventBus.fromJSON(data) requires pending_event_queue as an array of event ids')\n }\n const raw_pending_event_queue = record.pending_event_queue\n const pending_event_ids: string[] = []\n for (const item of raw_pending_event_queue) {\n if (typeof item === 'string') {\n pending_event_ids.push(item)\n }\n }\n bus.pending_event_queue = pending_event_ids\n .map((event_id) => bus.event_history.get(event_id))\n .filter((event): event is BaseEvent => Boolean(event))\n\n for (const event of bus.event_history.values()) {\n EventBus._linkEventResultHandlers(event, bus)\n }\n\n // Reset runtime execution state after restore. Queue/history/handlers are restored,\n // but lock internals should always restart from a clean default state.\n bus.in_flight_event_ids.clear()\n bus.runloop_running = false\n bus.locks.clear()\n bus.find_waiters.clear()\n\n return bus\n }\n\n get label(): string {\n return `${this.name}#${this.id.slice(-4)}`\n }\n\n removeEventFromPendingQueue(event: BaseEvent): number {\n const original_event = event._event_original ?? event\n let removed_count = 0\n for (let index = this.pending_event_queue.length - 1; index >= 0; index -= 1) {\n const queued_event = this.pending_event_queue[index]\n const queued_original = queued_event._event_original ?? queued_event\n if (queued_original.event_id !== original_event.event_id) {\n continue\n }\n this.pending_event_queue.splice(index, 1)\n removed_count += 1\n }\n return removed_count\n }\n\n isEventInFlightOrQueued(event_id: string): boolean {\n if (this.in_flight_event_ids.has(event_id)) {\n return true\n }\n for (const queued_event of this.pending_event_queue) {\n const queued_original = queued_event._event_original ?? queued_event\n if (queued_original.event_id === event_id) {\n return true\n }\n }\n return false\n }\n\n removeEventFromHistory(event_id: string): boolean {\n return this.event_history.delete(event_id)\n }\n\n private _raiseIfDestroyed(): void {\n if (this.destroyed) {\n throw new Error(`${this.toString()} has been destroyed and cannot be used again`)\n }\n }\n\n // destroy the event bus and all its state to allow for garbage collection\n destroy(clear?: boolean): Promise<void>\n destroy(options?: EventBusDestroyOptions): Promise<void>\n destroy(clear_or_options: boolean | EventBusDestroyOptions = true): Promise<void> {\n const clear = typeof clear_or_options === 'object' && clear_or_options !== null ? (clear_or_options.clear ?? true) : clear_or_options\n if (this.destroyed) {\n if (clear) {\n this.handlers.clear()\n this.handlers_by_key.clear()\n this.event_history.clear()\n this.middlewares.length = 0\n }\n return Promise.resolve()\n }\n const finish = (): void => {\n this.destroyed = true\n this.all_instances.discard(this)\n this.runloop_running = false\n for (const waiter of Array.from(this.find_waiters)) {\n if (waiter.timeout_id) {\n clearTimeout(waiter.timeout_id)\n }\n this.find_waiters.delete(waiter)\n waiter.resolve(null)\n }\n this.pending_event_queue.length = 0\n this.in_flight_event_ids.clear()\n this.locks.clear()\n if (!clear) {\n return\n }\n this.handlers.clear()\n this.handlers_by_key.clear()\n this.event_history.clear()\n this.middlewares.length = 0\n }\n finish()\n return Promise.resolve()\n }\n on<T extends BaseEvent>(event_pattern: EventClass<T>, handler: EventHandlerCallable<T>, options?: Partial<EventHandler>): EventHandler\n on<T extends BaseEvent>(\n event_pattern: string | '*',\n handler: UntypedEventHandlerFunction<T>,\n options?: Partial<EventHandler>\n ): EventHandler\n on(\n event_pattern: EventPattern | '*',\n handler: EventHandlerCallable | UntypedEventHandlerFunction,\n options: Partial<EventHandler> = {}\n ): EventHandler {\n this._raiseIfDestroyed()\n const normalized_key = normalizeEventPattern(event_pattern) // get string event_type or '*'\n const handler_name = EventHandler.handlerNameFromCallable(handler as EventHandlerCallable)\n const handler_entry = new EventHandler({\n handler: handler as EventHandlerCallable,\n handler_name,\n handler_registered_at: monotonicDatetime(),\n event_pattern: normalized_key,\n eventbus_name: this.name,\n eventbus_id: this.id,\n ...options,\n })\n if (this.event_handler_detect_file_paths) {\n // optionally perform (expensive) file path detection for the handler using Error().stack introspection\n // makes logs much more useful for debugging, but is expensive to do if not needed\n handler_entry._detectHandlerFilePath()\n }\n\n this.handlers.set(handler_entry.id, handler_entry)\n const ids = this.handlers_by_key.get(handler_entry.event_pattern)\n if (ids) ids.push(handler_entry.id)\n else this.handlers_by_key.set(handler_entry.event_pattern, [handler_entry.id])\n this.scheduleMicrotask(() => {\n void this._onBusHandlersChange(handler_entry, true)\n })\n return handler_entry\n }\n\n off<T extends BaseEvent>(event_pattern: EventPattern<T> | '*', handler?: EventHandlerCallable<T> | string | EventHandler): void {\n this._raiseIfDestroyed()\n const normalized_key = normalizeEventPattern(event_pattern)\n if (typeof handler === 'object' && handler instanceof EventHandler && handler.id !== undefined) {\n handler = handler.id\n }\n const match_by_id = typeof handler === 'string'\n for (const entry of this.handlers.values()) {\n if (entry.event_pattern !== normalized_key) {\n continue\n }\n const handler_id = entry.id\n if (handler === undefined || (match_by_id ? handler_id === handler : entry.handler === (handler as EventHandlerCallable))) {\n this.handlers.delete(handler_id)\n this._removeIndexedHandler(entry.event_pattern, handler_id)\n this.scheduleMicrotask(() => {\n void this._onBusHandlersChange(entry, false)\n })\n }\n }\n }\n\n emit<T extends BaseEvent>(event: T): T {\n this._raiseIfDestroyed()\n const original_event = event._event_original ?? event // if event is a bus-scoped proxy already, get the original underlying event object\n const current_result = this.locks._getRawActiveHandlerResultForCurrentAsyncContext()\n if (\n current_result &&\n current_result.status !== 'pending' &&\n current_result.status !== 'started' &&\n (current_result.error instanceof EventHandlerTimeoutError ||\n current_result.error instanceof EventHandlerCancelledError ||\n current_result.error instanceof EventHandlerAbortedError)\n ) {\n return original_event as T\n }\n if (!original_event.event_bus) {\n // if we are the first bus to emit this event, set the event_bus property on the original event object\n original_event.event_bus = this\n }\n if (!Array.isArray(original_event.event_path)) {\n original_event.event_path = []\n }\n if (original_event._getDispatchContext() === undefined) {\n // when used in fastify/nextjs/other contexts with tracing based on AsyncLocalStorage in node\n // we want to capture the context at the emit site and use it when running handlers\n // because events may be handled async in a separate context than the emit site\n original_event._setDispatchContext(captureAsyncContext())\n }\n if (original_event.event_path.includes(this.label) || this._hasProcessedEvent(original_event)) {\n return this._getEventProxyScopedToThisBus(original_event) as T\n }\n\n if (!original_event.event_path.includes(this.label)) {\n original_event.event_path.push(this.label)\n }\n\n if (original_event.event_parent_id && original_event.event_emitted_by_handler_id) {\n const parent_result = original_event.event_parent?.event_results.get(original_event.event_emitted_by_handler_id)\n if (parent_result) {\n parent_result._linkEmittedChildEvent(original_event)\n }\n }\n\n if (\n this.event_history.max_history_size !== null &&\n this.event_history.max_history_size > 0 &&\n !this.event_history.max_history_drop &&\n this.event_history.size >= this.event_history.max_history_size\n ) {\n throw new Error(\n `${this.toString()}.emit(${original_event.event_type}) rejected: history limit reached (${this.event_history.size}/${this.event_history.max_history_size}); set event_history.max_history_drop=true to drop old history instead.`\n )\n }\n\n this.event_history.addEvent(original_event)\n this.event_history.trimEventHistory({\n is_event_complete: (candidate_event) => candidate_event.event_status === 'completed',\n on_remove: (candidate_event) => candidate_event._gc(),\n owner_label: this.toString(),\n max_history_size: this.event_history.max_history_size,\n max_history_drop: this.event_history.max_history_drop,\n })\n this._resolveFindWaiters(original_event)\n\n original_event.event_pending_bus_count += 1\n this.pending_event_queue.push(original_event)\n if (this.locks.getLockForEvent(original_event) === null) {\n this._startParallelEventTaskFromQueue(original_event)\n } else {\n this._startRunloop()\n }\n\n return this._getEventProxyScopedToThisBus(original_event) as T\n }\n\n // alias for emit\n dispatch<T extends BaseEvent>(event: T): T {\n return this.emit(event)\n }\n\n // find a recent event or wait for a future event that matches some criteria\n find(event_pattern: '*', options?: FindOptions<BaseEvent>): Promise<BaseEvent | null>\n find(event_pattern: '*', where: (event: BaseEvent) => boolean, options?: FindOptions<BaseEvent>): Promise<BaseEvent | null>\n find<T extends BaseEvent>(event_pattern: EventPattern<T>, options?: FindOptions<T>): Promise<T | null>\n find<T extends BaseEvent>(event_pattern: EventPattern<T>, where: (event: T) => boolean, options?: FindOptions<T>): Promise<T | null>\n async find<T extends BaseEvent>(\n event_pattern: EventPattern<T> | '*',\n where_or_options: ((event: T) => boolean) | FindOptions<T> = {},\n maybe_options: FindOptions<T> = {}\n ): Promise<T | null> {\n const where = typeof where_or_options === 'function' ? where_or_options : () => true\n const options = typeof where_or_options === 'function' ? maybe_options : where_or_options\n // `limit` field-equality filter would collide with filter()'s cap arg; route it through `where`.\n let effective_where = where\n let effective_options: FindOptions<T> = options\n if (Object.prototype.hasOwnProperty.call(options, 'limit')) {\n const { limit: limit_field_value, ...rest } = options as FindOptions<T> & { limit: unknown }\n const inner_where = where\n effective_where = (event: T) => (event as unknown as Record<string, unknown>).limit === limit_field_value && inner_where(event)\n effective_options = rest as unknown as FindOptions<T>\n }\n const results = await this.filter(event_pattern as EventPattern<T> | '*', effective_where, { ...effective_options, limit: 1 })\n return results.length > 0 ? results[0] : null\n }\n\n // same as find() but returns the list of all matching events (newest to oldest)\n // optional `limit` arg caps the number of results returned\n filter(event_pattern: '*', options?: FilterOptions<BaseEvent>): Promise<BaseEvent[]>\n filter(event_pattern: '*', where: (event: BaseEvent) => boolean, options?: FilterOptions<BaseEvent>): Promise<BaseEvent[]>\n filter<T extends BaseEvent>(event_pattern: EventPattern<T>, options?: FilterOptions<T>): Promise<T[]>\n filter<T extends BaseEvent>(event_pattern: EventPattern<T>, where: (event: T) => boolean, options?: FilterOptions<T>): Promise<T[]>\n async filter<T extends BaseEvent>(\n event_pattern: EventPattern<T> | '*',\n where_or_options: ((event: T) => boolean) | FilterOptions<T> = {},\n maybe_options: FilterOptions<T> = {}\n ): Promise<T[]> {\n this._raiseIfDestroyed()\n const where = typeof where_or_options === 'function' ? where_or_options : () => true\n const options = typeof where_or_options === 'function' ? maybe_options : where_or_options\n const matches = await this.event_history.filter(event_pattern as EventPattern<T> | '*', where, {\n ...options,\n event_is_child_of: (event, ancestor) => this.eventIsChildOf(event, ancestor),\n wait_for_future_match: (normalized_event_pattern, matches_fn, future) =>\n this._waitForFutureMatch(normalized_event_pattern, matches_fn, future),\n })\n return matches.map((match) => this._getEventProxyScopedToThisBus(match) as T)\n }\n\n private async _waitForFutureMatch(\n event_pattern: string | '*',\n matches: (event: BaseEvent) => boolean,\n future: boolean | number\n ): Promise<BaseEvent | null> {\n if (future === false) {\n return null\n }\n return await new Promise<BaseEvent | null>((resolve) => {\n const waiter: EphemeralFindEventHandler = {\n event_pattern,\n matches,\n resolve: (event) => resolve(event),\n }\n if (future !== true) {\n const timeout_ms = Math.max(0, Number(future)) * 1000\n waiter.timeout_id = setTimeout(() => {\n this.find_waiters.delete(waiter)\n resolve(null)\n }, timeout_ms)\n }\n this.find_waiters.add(waiter)\n })\n }\n\n async waitUntilIdle(timeout: number | null = null): Promise<boolean> {\n this._raiseIfDestroyed()\n return await this.locks.waitForIdle(timeout)\n }\n\n // Weak idle check: only checks if handlers are idle, doesnt check that the queue is empty\n isIdle(): boolean {\n for (const event of this.event_history.values()) {\n for (const result of event.event_results.values()) {\n if (result.eventbus_id !== this.id) {\n continue\n }\n if (result.status === 'pending' || result.status === 'started') {\n return false\n }\n }\n }\n return true // no handlers are pending or started\n }\n\n // Stronger idle check: no queued work, no in-flight processing, _runloop not\n // active, and no handlers pending/running for this bus.\n isIdleAndQueueEmpty(): boolean {\n return this.pending_event_queue.length === 0 && this.in_flight_event_ids.size === 0 && this.isIdle() && !this.runloop_running\n }\n\n eventIsChildOf(child_event: BaseEvent, parent_event: BaseEvent): boolean {\n if (child_event.event_id === parent_event.event_id) {\n return false\n }\n\n let current_parent_id = child_event.event_parent_id\n while (current_parent_id) {\n if (current_parent_id === parent_event.event_id) {\n return true\n }\n const parent = this.event_history.get(current_parent_id)\n if (!parent) {\n return false\n }\n current_parent_id = parent.event_parent_id\n }\n return false\n }\n\n eventIsParentOf(parent_event: BaseEvent, child_event: BaseEvent): boolean {\n return this.eventIsChildOf(child_event, parent_event)\n }\n\n // return a full detailed tree diagram of all events and results on this bus\n logTree(): string {\n return logTree(this)\n }\n\n // Resolve an event id from this bus first, then across all known buses.\n findEventById(event_id: string): BaseEvent | null {\n return this.event_history.get(event_id) ?? this.all_instances.findEventById(event_id)\n }\n\n private _startRunloop(): void {\n this._raiseIfDestroyed()\n if (this.runloop_running) {\n return\n }\n this.runloop_running = true\n this.scheduleMicrotask(() => {\n void this._runloop()\n })\n }\n\n private _startParallelEventTaskFromQueue(event: BaseEvent): void {\n if (this.in_flight_event_ids.has(event.event_id)) {\n return\n }\n const queue_index = this.pending_event_queue.indexOf(event)\n if (queue_index >= 0) {\n this.pending_event_queue.splice(queue_index, 1)\n } else if (event.event_status === 'completed') {\n return\n }\n this.in_flight_event_ids.add(event.event_id)\n this.scheduleMicrotask(() => {\n void this._processEvent(event)\n })\n }\n\n // schedule the processing of an event on the event bus by its normal _runloop\n // optionally using a pre-acquired lock if we're inside handling of a parent event\n private async _processEvent(\n event: BaseEvent,\n options: {\n bypass_event_locks?: boolean\n pre_acquired_lock?: AsyncLock | null\n } = {}\n ): Promise<void> {\n let pending_entries: Array<{\n handler: EventHandler\n result: EventResult\n }> = []\n try {\n if (this._hasProcessedEvent(event)) {\n return\n }\n const scoped_event = this._getEventProxyScopedToThisBus(event)\n await this._onEventChange(scoped_event, 'pending')\n event._markStarted()\n pending_entries = event._createPendingHandlerResults(this)\n const resolved_event_timeout = event.event_timeout ?? this.event_timeout\n const resolved_event_slow_timeout = event.event_slow_timeout ?? this.event_slow_timeout\n if (this.middlewares.length > 0) {\n for (const entry of pending_entries) {\n await this._onEventResultChange(scoped_event, entry.result, 'pending')\n }\n }\n await this.locks._runWithEventLock(\n event,\n () =>\n this._runHandlersWithTimeout(event, pending_entries, resolved_event_timeout, () =>\n _runWithSlowMonitor(event._createSlowEventWarningTimer(resolved_event_slow_timeout, this.name), () =>\n scoped_event._runHandlers(pending_entries)\n )\n ),\n options\n )\n this._markEventCompletedIfNeeded(event)\n } finally {\n if (options.pre_acquired_lock) {\n options.pre_acquired_lock.release()\n }\n this.in_flight_event_ids.delete(event.event_id)\n this.locks._notifyIdleListeners()\n }\n }\n\n // Called when a handler does `await child.now()` \u2014 processes the child event\n // immediately (\"queue-jump\") instead of waiting for the _runloop to pick it up.\n //\n // Yield-and-reacquire: if the calling handler holds a handler concurrency lock,\n // we temporarily release it so child handlers on the same bus can acquire it\n // (preventing deadlock for serial handler mode). We re-acquire after\n // the child completes so the parent handler can continue with the lock held.\n async _processEventImmediately<T extends BaseEvent>(event: T, handler_result?: EventResult): Promise<T> {\n const original_event = event._event_original ?? event\n // Find the handler result for the current await call site. Proxy-provided\n // context covers event.emit(...); async-local context lets awaited bus.emit(...)\n // events queue-jump without implicitly changing their parentage.\n const proxy_result = handler_result?.status === 'started' ? handler_result : undefined\n const currently_active_event_result = proxy_result ?? this.locks._getActiveHandlerResultForCurrentAsyncContext()\n if (!currently_active_event_result) {\n const queue_index = this.pending_event_queue.indexOf(original_event)\n const event_lock = this.locks.getLockForEvent(original_event)\n const can_process_queue_head_normally =\n queue_index === 0 &&\n !this.locks._isPaused() &&\n !this.in_flight_event_ids.has(original_event.event_id) &&\n !this._hasProcessedEvent(original_event) &&\n (event_lock === null || event_lock.in_use === 0)\n if (can_process_queue_head_normally) {\n let pre_acquired_lock: AsyncLock | null = null\n if (event_lock) {\n await event_lock.acquire()\n pre_acquired_lock = event_lock\n }\n const queue_head = this.pending_event_queue[0]\n const queue_head_original = queue_head?._event_original ?? queue_head\n if (\n queue_head_original === original_event &&\n !this.locks._isPaused() &&\n !this.in_flight_event_ids.has(original_event.event_id) &&\n !this._hasProcessedEvent(original_event)\n ) {\n this.pending_event_queue.shift()\n this.in_flight_event_ids.add(original_event.event_id)\n await this._processEvent(original_event, {\n bypass_event_locks: true,\n pre_acquired_lock,\n })\n if (original_event.event_status !== 'completed') {\n await this._processEventImmediatelyAcrossBuses(original_event)\n }\n return event\n }\n pre_acquired_lock?.release()\n }\n await this._processEventImmediatelyAcrossBuses(original_event)\n return event\n }\n\n const active_parent = currently_active_event_result.event._event_original ?? currently_active_event_result.event\n const is_child_of_active_handler =\n original_event.event_parent_id === active_parent.event_id &&\n original_event.event_emitted_by_handler_id === currently_active_event_result.handler_id &&\n currently_active_event_result.event_children.some((child) => (child._event_original ?? child).event_id === original_event.event_id)\n if (is_child_of_active_handler) {\n original_event.event_blocks_parent_completion = true\n }\n\n // Serial event modes need the runloop paused while the queue-jumped child\n // runs so queued siblings cannot overshoot the suspended parent handler.\n // Parallel events have no event lock, so pausing here would incorrectly\n // block later parallel work emitted by the same parent.\n if (this.locks.getLockForEvent(original_event) !== null) {\n currently_active_event_result._ensureQueueJumpPause(this)\n }\n if (original_event.event_status === 'completed') {\n return event\n }\n\n // re-endter event-level handler lock if needed\n if (currently_active_event_result._lock) {\n await currently_active_event_result._lock.runQueueJump(this._processEventImmediatelyAcrossBuses.bind(this, original_event))\n return event\n }\n\n await this._processEventImmediatelyAcrossBuses(original_event)\n return event\n }\n\n // Processes a queue-jumped event across all buses that have it emitted.\n // Called from _processEventImmediately after the parent handler's lock has been yielded.\n private async _processEventImmediatelyAcrossBuses(event: BaseEvent): Promise<void> {\n // Determine which event lock the initiating bus resolves to, so we can\n // detect when other buses share the same instance (global-serial).\n const initiating_event_lock = this.locks.getLockForEvent(event)\n\n for (;;) {\n // Use event_path ordering to pick candidate buses and filter out buses\n // that haven't seen the event or already processed it. Forwarding\n // handlers can append new buses while this method is already running, so\n // this list must be rebuilt until the event is fully complete.\n const ordered: EventBus[] = []\n const seen = new Set<EventBus>()\n const event_path = Array.isArray(event.event_path) ? event.event_path : []\n for (const label of event_path) {\n for (const bus of this.all_instances) {\n if (bus.label !== label) {\n continue\n }\n if (!bus.event_history.has(event.event_id)) {\n continue\n }\n if (bus._hasProcessedEvent(event)) {\n continue\n }\n if (!seen.has(bus)) {\n ordered.push(bus)\n seen.add(bus)\n }\n }\n }\n if (!seen.has(this) && this.event_history.has(event.event_id) && !this._hasProcessedEvent(event)) {\n ordered.push(this)\n }\n\n const pause_releases: Array<() => void> = []\n let processed_bus = false\n try {\n for (const bus of ordered) {\n if (bus !== this) {\n pause_releases.push(bus.locks._requestRunloopPause())\n }\n }\n\n for (const bus of ordered) {\n const index = bus.pending_event_queue.indexOf(event)\n if (index >= 0) {\n bus.pending_event_queue.splice(index, 1)\n }\n if (bus._hasProcessedEvent(event)) {\n continue\n }\n if (bus.in_flight_event_ids.has(event.event_id)) {\n continue\n }\n bus.in_flight_event_ids.add(event.event_id)\n processed_bus = true\n\n // Bypass event lock on the initiating bus (we're already inside a handler\n // that acquired it). For other buses, only bypass if they resolve to the same\n // lock instance (global-serial shares one lock across all buses).\n const bus_event_lock = bus.locks.getLockForEvent(event)\n const should_bypass_event_lock = bus === this || (initiating_event_lock !== null && bus_event_lock === initiating_event_lock)\n\n await bus._processEvent(event, {\n bypass_event_locks: should_bypass_event_lock,\n })\n }\n } finally {\n for (const release of pause_releases) {\n release()\n }\n }\n\n if (event.event_status === 'completed') {\n return\n }\n if (!processed_bus) {\n await new Promise((resolve) => setTimeout(resolve, 1))\n }\n }\n }\n\n private async _runloop(): Promise<void> {\n for (;;) {\n while (this.pending_event_queue.length > 0) {\n await Promise.resolve()\n if (this.locks._isPaused()) {\n await this.locks._waitUntilRunloopResumed()\n continue\n }\n const next_event = this.pending_event_queue[0]\n if (!next_event) {\n continue\n }\n const original_event = next_event._event_original ?? next_event\n if (this._hasProcessedEvent(original_event)) {\n this.pending_event_queue.shift()\n continue\n }\n let pre_acquired_lock: AsyncLock | null = null\n const event_lock = this.locks.getLockForEvent(original_event)\n if (event_lock) {\n await event_lock.acquire()\n pre_acquired_lock = event_lock\n }\n // Queue head may have changed while waiting for the lock\n // (e.g. now() processing the head immediately). Revalidate\n // before mutating the queue to avoid removing the wrong event.\n const current_head = this.pending_event_queue[0]\n const current_head_original = current_head?._event_original ?? current_head\n if (current_head_original !== original_event) {\n if (pre_acquired_lock) {\n pre_acquired_lock.release()\n }\n continue\n }\n this.pending_event_queue.shift()\n if (this.in_flight_event_ids.has(original_event.event_id)) {\n if (pre_acquired_lock) {\n pre_acquired_lock.release()\n }\n continue\n }\n this.in_flight_event_ids.add(original_event.event_id)\n void this._processEvent(original_event, {\n bypass_event_locks: true,\n pre_acquired_lock,\n })\n await Promise.resolve()\n }\n this.runloop_running = false\n if (this.pending_event_queue.length > 0) {\n this._startRunloop()\n return\n }\n this.locks._notifyIdleListeners()\n return\n }\n }\n\n // check if an event has been processed (and completed) by this bus\n _hasProcessedEvent(event: BaseEvent): boolean {\n const results = Array.from(event.event_results.values()).filter((result) => result.eventbus_id === this.id)\n if (results.length === 0) {\n return false\n }\n return results.every((result) => result.status === 'completed' || result.status === 'error')\n }\n\n // get a proxy wrapper around an Event that will automatically link emitted child events to this bus and handler\n // proxy is what gets passed into the handler, if handler does event.emit(...) to dispatch child events,\n // the proxy auto-sets event.parent_event_id and event.event_emitted_by_handler_id\n _getEventProxyScopedToThisBus<T extends BaseEvent>(event: T, handler_result?: EventResult): T {\n const original_event = event._event_original ?? event\n const bus = this\n const parent_event_id = original_event.event_id\n const bus_proxy = new Proxy(bus, {\n get(target, prop, receiver) {\n if (prop === '_processEventImmediately') {\n const runner = Reflect.get(target, prop, receiver) as EventBus['_processEventImmediately']\n const process_event_immediately = <TChild extends BaseEvent>(child_event: TChild): Promise<TChild> => {\n return runner.call(target, child_event, handler_result) as Promise<TChild>\n }\n return process_event_immediately\n }\n if (prop === 'dispatch' || prop === 'emit') {\n const emit_child_event = <TChild extends BaseEvent>(child_event: TChild): TChild => {\n const original_child = child_event._event_original ?? child_event\n const handler_result_is_terminal = handler_result && handler_result.status !== 'pending' && handler_result.status !== 'started'\n if (\n handler_result_is_terminal &&\n (handler_result.error instanceof EventHandlerTimeoutError ||\n handler_result.error instanceof EventHandlerCancelledError ||\n handler_result.error instanceof EventHandlerAbortedError)\n ) {\n return original_child as TChild\n }\n if (handler_result && !handler_result_is_terminal) {\n handler_result._linkEmittedChildEvent(original_child)\n } else if (!original_child.event_parent_id && original_child.event_id !== parent_event_id) {\n // fallback for non-handler scoped emit/dispatch\n original_child.event_parent_id = parent_event_id\n }\n const dispatcher = Reflect.get(target, prop, receiver) as EventBus['dispatch']\n const dispatched = dispatcher.call(target, original_child)\n return target._getEventProxyScopedToThisBus(dispatched as TChild, handler_result)\n }\n return emit_child_event\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n const scoped = new Proxy(original_event, {\n get(target, prop, receiver) {\n if (prop === 'event_bus') {\n return bus_proxy\n }\n if (prop === '_event_original') {\n return target\n }\n return Reflect.get(target, prop, receiver)\n },\n set(target, prop, value) {\n if (prop === 'event_bus') {\n return true\n }\n return Reflect.set(target, prop, value, target)\n },\n has(target, prop) {\n if (prop === 'event_bus') {\n return true\n }\n if (prop === '_event_original') {\n return true\n }\n return Reflect.has(target, prop)\n },\n })\n\n return scoped as T\n }\n\n private _resolveFindWaiters(event: BaseEvent): void {\n for (const waiter of Array.from(this.find_waiters)) {\n if ((waiter.event_pattern !== '*' && event.event_type !== waiter.event_pattern) || !waiter.matches(event)) {\n continue\n }\n if (waiter.timeout_id) {\n clearTimeout(waiter.timeout_id)\n }\n this.find_waiters.delete(waiter)\n waiter.resolve(event)\n }\n }\n\n _getHandlersForEvent(event: BaseEvent): EventHandler[] {\n const handlers: EventHandler[] = []\n for (const key of [event.event_type, '*']) {\n const ids = this.handlers_by_key.get(key)\n if (!ids) continue\n for (const id of ids) {\n const entry = this.handlers.get(id)\n if (entry) handlers.push(entry)\n }\n }\n return handlers\n }\n\n private _removeIndexedHandler(event_pattern: string | '*', handler_id: string): void {\n const ids = this.handlers_by_key.get(event_pattern)\n if (!ids) return\n const idx = ids.indexOf(handler_id)\n if (idx < 0) return\n ids.splice(idx, 1)\n if (ids.length === 0) this.handlers_by_key.delete(event_pattern)\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA8C;AAC9C,0BAA6B;AAE7B,2BAAoC;AACpC,oBAAqD;AACrD,yBAMO;AACP,0BAOO;AAEP,qBAAwB;AACxB,kBAA6B;AAC7B,qBAAkC;AAElC,mBAAsC;AA6C/B,MAAM,uBAAuB;AAAA,EAC1B,YAAY,oBAAI,IAAuB;AAAA,EAE/C,IAAI,KAAqB;AACvB,SAAK,UAAU,IAAI,IAAI,QAAQ,GAAG,CAAC;AAAA,EACrC;AAAA,EAEA,QAAQ,KAAqB;AAC3B,eAAW,OAAO,KAAK,WAAW;AAChC,YAAM,UAAU,IAAI,MAAM;AAC1B,UAAI,CAAC,WAAW,YAAY,KAAK;AAC/B,aAAK,UAAU,OAAO,GAAG;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAI,KAAwB;AAC1B,eAAW,OAAO,KAAK,WAAW;AAChC,YAAM,UAAU,IAAI,MAAM;AAC1B,UAAI,CAAC,SAAS;AACZ,aAAK,UAAU,OAAO,GAAG;AACzB;AAAA,MACF;AACA,UAAI,YAAY,KAAK;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAe;AACjB,QAAI,QAAQ;AACZ,eAAW,OAAO,KAAK,WAAW;AAChC,UAAI,IAAI,MAAM,GAAG;AACf,iBAAS;AAAA,MACX,OAAO;AACL,aAAK,UAAU,OAAO,GAAG;AAAA,MAC3B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,EAAE,OAAO,QAAQ,IAAgC;AAC/C,eAAW,OAAO,KAAK,WAAW;AAChC,YAAM,MAAM,IAAI,MAAM;AACtB,UAAI,KAAK;AACP,cAAM;AAAA,MACR,OAAO;AACL,aAAK,UAAU,OAAO,GAAG;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,QAAsC;AAChD,eAAW,OAAO,MAAM;AACtB,UAAI,IAAI,OAAO,QAAQ;AACrB,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,UAAoC;AAChD,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,IAAI,cAAc,SAAS,QAAQ;AACjD,UAAI,OAAO;AACT,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEO,MAAM,SAAS;AAAA,EACpB,OAAe,2BAA2B,oBAAI,QAA0C;AAAA,EACxF,OAAe,oCAAoC,oBAAI,QAA6B;AAAA,EAEpF,OAAe,0BAA0B,gBAAkD;AACzF,UAAM,oBAAoB,SAAS,yBAAyB,IAAI,cAAc;AAC9E,QAAI,mBAAmB;AACrB,aAAO;AAAA,IACT;AACA,UAAM,mBAAmB,IAAI,uBAAuB;AACpD,aAAS,yBAAyB,IAAI,gBAAgB,gBAAgB;AACtE,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,iCAAiC,gBAAqC;AACnF,UAAM,gBAAgB,SAAS,kCAAkC,IAAI,cAAc;AACnF,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AACA,UAAM,eAAe,IAAI,6BAAU,CAAC;AACpC,aAAS,kCAAkC,IAAI,gBAAgB,YAAY;AAC3E,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,gBAAwC;AACjD,WAAO,SAAS,0BAA0B,IAAI;AAAA,EAChD;AAAA,EAEA,IAAI,gBAAwC;AAC1C,WAAO,SAAS,0BAA0B,KAAK,WAAuB;AAAA,EACxE;AAAA,EAEA,IAAI,gCAA2C;AAC7C,WAAO,SAAS,iCAAiC,KAAK,WAAuB;AAAA,EAC/E;AAAA,EAEA;AAAA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACQ;AAAA,EAER,OAAe,qBAAqB,aAA+D;AACjG,UAAM,aAAmC,CAAC;AAC1C,eAAW,cAAc,eAAe,CAAC,GAAG;AAC1C,UAAI,CAAC,YAAY;AACf;AAAA,MACF;AACA,UAAI,OAAO,eAAe,YAAY;AACpC,mBAAW,KAAK,IAAK,WAAsC,CAAC;AAAA,MAC9D,OAAO;AACL,mBAAW,KAAK,UAAgC;AAAA,MAClD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,OAAe,YAAY,UAA2B,CAAC,GAAG;AACpE,SAAK,KAAK,QAAQ,UAAM,YAAAA,IAAO;AAC/B,SAAK,OAAO;AAGZ,SAAK,oBAAoB,QAAQ,qBAAqB;AACtD,SAAK,4BAA4B,QAAQ,6BAA6B;AACtE,SAAK,2BAA2B,QAAQ,4BAA4B;AACpE,SAAK,kCAAkC,QAAQ,mCAAmC;AAClF,SAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,SAAK,6BAA6B,QAAQ,8BAA8B;AACxE,SAAK,qBAAqB,QAAQ,sBAAsB;AAGxD,SAAK,kBAAkB;AACvB,SAAK,WAAW,oBAAI,IAAI;AACxB,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,SAAK,eAAe,oBAAI,IAAI;AAC5B,SAAK,gBAAgB,IAAI,iCAAa;AAAA,MACpC,kBAAkB,QAAQ,qBAAqB,SAAY,MAAM,QAAQ;AAAA,MACzE,kBAAkB,QAAQ,oBAAoB;AAAA,IAChD,CAAC;AACD,SAAK,sBAAsB,CAAC;AAC5B,SAAK,sBAAsB,oBAAI,IAAI;AACnC,SAAK,QAAQ,IAAI,+BAAY,IAAI;AACjC,SAAK,cAAc,SAAS,qBAAqB,QAAQ,WAAW;AACpE,SAAK,YAAY;AAEjB,SAAK,cAAc,IAAI,IAAI;AAE3B,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AACvC,SAAK,OAAO,KAAK,KAAK,KAAK,IAAI;AAAA,EACjC;AAAA,EAEA,WAAmB;AACjB,WAAO,GAAG,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;AAAA,EAC1C;AAAA,EAEA,kBAAkB,IAAsB;AACtC,QAAI,OAAO,mBAAmB,YAAY;AACxC,qBAAe,EAAE;AACjB;AAAA,IACF;AACA,SAAK,QAAQ,QAAQ,EAAE,KAAK,EAAE;AAAA,EAChC;AAAA,EAEA,MAAc,mBAAmB,MAAgC,MAAgC;AAC/F,QAAI,KAAK,YAAY,WAAW,GAAG;AACjC;AAAA,IACF;AACA,eAAW,cAAc,KAAK,aAAa;AACzC,YAAM,WAAW,WAAW,IAAI;AAChC,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AACA,YAAO,SAA+D,MAAM,YAAY,IAAI;AAAA,IAC9F;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,OAAkB,QAA4D;AAChG,UAAM,KAAK,eAAe,OAAO,MAAM;AAAA,EACzC;AAAA,EAEA,MAAM,oBAAoB,OAAkB,QAAqB,QAA4D;AAC3H,UAAM,KAAK,qBAAqB,OAAO,QAAQ,MAAM;AAAA,EACvD;AAAA,EAEA,MAAc,eAAe,OAAkB,QAA4D;AACzG,UAAM,KAAK,mBAAmB,iBAAiB,CAAC,MAAM,OAAO,MAAM,CAAC;AAAA,EACtE;AAAA,EAEA,MAAc,qBAAqB,OAAkB,QAAqB,QAA4D;AACpI,UAAM,KAAK,mBAAmB,uBAAuB,CAAC,MAAM,OAAO,QAAQ,MAAM,CAAC;AAAA,EACpF;AAAA,EAEA,MAAc,qBAAqB,SAAuB,YAAoC;AAC5F,UAAM,KAAK,mBAAmB,uBAAuB,CAAC,MAAM,SAAS,UAAU,CAAC;AAAA,EAClF;AAAA,EAEQ,sBACN,OACA,iBAIA,eACM;AACN,UAAM,kBAAkB,cAAc,mBAAmB,MAAM,iBAAiB;AAChF,UAAM,8BAA8B,aAAa;AAEjD,eAAW,SAAS,iBAAiB;AACnC,YAAM,SAAS,MAAM;AACrB,UAAI,OAAO,WAAW,aAAa;AACjC;AAAA,MACF;AACA,UAAI,OAAO,WAAW,SAAS;AAC7B;AAAA,MACF;AACA,UAAI,OAAO,WAAW,WAAW;AAC/B,eAAO,OAAO,eAAe;AAC7B,eAAO,wBAAwB;AAC/B,cAAM,gBAAgB,IAAI,6CAAyB,gDAAgD;AAAA,UACjG,cAAc;AAAA,UACd;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AACD,eAAO,WAAW,aAAa;AAC/B,eAAO,aAAa,aAAa;AACjC;AAAA,MACF;AACA,YAAM,kBAAkB,IAAI,+CAA2B,kDAAkD;AAAA,QACvG,cAAc;AAAA,QACd;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AACD,aAAO,WAAW,eAAe;AAAA,IACnC;AAEA,UAAM,0BAA0B,KAAK,IAAI,GAAG,MAAM,0BAA0B,CAAC;AAC7E,UAAM,eAAe;AAAA,EACvB;AAAA,EAEQ,yBACN,OACA,iBAIA,iBAC0B;AAC1B,UAAM,iBACJ,gBAAgB,KAAK,CAAC,UAAU,MAAM,OAAO,WAAW,SAAS,KACjE,gBAAgB,KAAK,CAAC,UAAU,MAAM,OAAO,WAAW,SAAS,KACjE,gBAAgB,CAAC;AACnB,WAAO,IAAI;AAAA,MACT,GAAG,KAAK,SAAS,CAAC,OAAO,MAAM,SAAS,CAAC,KAAK,eAAe,OAAO,QAAQ,SAAS,CAAC,qBAAqB,eAAe;AAAA,MAC1H;AAAA,QACE,cAAc,eAAe;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,wBACZ,OACA,iBAIA,eACA,IACe;AACf,QAAI;AACF,UAAI,kBAAkB,QAAQ,iBAAiB,KAAK,gBAAgB,WAAW,GAAG;AAChF,cAAM,GAAG;AAAA,MACX,OAAO;AACL,kBAAM,+BAAgB,eAAe,MAAM,KAAK,yBAAyB,OAAO,iBAAiB,aAAa,GAAG,EAAE;AAAA,MACrH;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,8CAA0B;AAC7C,aAAK,sBAAsB,OAAO,iBAAiB,KAAK;AACxD;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,4BAA4B,OAAwB;AAC1D,QAAI,MAAM,iBAAiB,aAAa;AACtC,YAAM,0BAA0B,KAAK,IAAI,GAAG,MAAM,0BAA0B,CAAC;AAC7E,YAAM,eAAe,KAAK;AAAA,IAC5B;AACA,QACE,KAAK,cAAc,qBAAqB,QACxC,KAAK,cAAc,mBAAmB,KACtC,KAAK,cAAc,OAAO,KAAK,cAAc,kBAC7C;AACA,WAAK,cAAc,iBAAiB;AAAA,QAClC,mBAAmB,CAAC,oBAAoB,gBAAgB,iBAAiB;AAAA,QACzE,WAAW,CAAC,oBAAoB,gBAAgB,IAAI;AAAA,QACpD,aAAa,KAAK,SAAS;AAAA,QAC3B,kBAAkB,KAAK,cAAc;AAAA,QACrC,kBAAkB,KAAK,cAAc;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,SAAuB;AACrB,UAAM,WAA6C,CAAC;AACpD,eAAW,CAAC,YAAY,OAAO,KAAK,KAAK,SAAS,QAAQ,GAAG;AAC3D,eAAS,UAAU,IAAI,QAAQ,OAAO;AAAA,IACxC;AAEA,UAAM,kBAA4C,CAAC;AACnD,eAAW,CAAC,KAAK,GAAG,KAAK,KAAK,gBAAgB,QAAQ,GAAG;AACvD,sBAAgB,GAAG,IAAI,CAAC,GAAG,GAAG;AAAA,IAChC;AAEA,UAAM,gBAA+C,CAAC;AACtD,eAAW,CAAC,UAAU,KAAK,KAAK,KAAK,cAAc,QAAQ,GAAG;AAC5D,oBAAc,QAAQ,IAAI,MAAM,OAAO;AAAA,IACzC;AAEA,UAAM,sBAAgC,CAAC;AACvC,eAAW,SAAS,KAAK,qBAAqB;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,CAAC,cAAc,QAAQ,GAAG;AAC5B,sBAAc,QAAQ,IAAI,MAAM,OAAO;AAAA,MACzC;AACA,0BAAoB,KAAK,QAAQ;AAAA,IACnC;AAEA,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,kBAAkB,KAAK,cAAc;AAAA,MACrC,kBAAkB,KAAK,cAAc;AAAA,MACrC,mBAAmB,KAAK;AAAA,MACxB,eAAe,KAAK;AAAA,MACpB,oBAAoB,KAAK;AAAA,MACzB,2BAA2B,KAAK;AAAA,MAChC,0BAA0B,KAAK;AAAA,MAC/B,4BAA4B,KAAK;AAAA,MACjC,iCAAiC,KAAK;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAe,iBAAuC;AACpD,YAAQ,MAAM;AAAA,EAChB;AAAA,EAEA,OAAe,oBAAoB,KAAe,eAAuB,YAA0B;AACjG,UAAM,MAAM,IAAI,gBAAgB,IAAI,aAAa;AACjD,QAAI,KAAK;AACP,UAAI,CAAC,IAAI,SAAS,UAAU,GAAG;AAC7B,YAAI,KAAK,UAAU;AAAA,MACrB;AACA;AAAA,IACF;AACA,QAAI,gBAAgB,IAAI,eAAe,CAAC,UAAU,CAAC;AAAA,EACrD;AAAA,EAEA,OAAe,yBAAyB,OAAkB,KAAqB;AAC7E,eAAW,CAAC,SAAS,MAAM,KAAK,MAAM,KAAK,MAAM,cAAc,QAAQ,CAAC,GAAG;AACzE,YAAM,aAAa,OAAO;AAC1B,YAAM,mBAAmB,IAAI,SAAS,IAAI,UAAU;AACpD,UAAI,kBAAkB;AACpB,eAAO,UAAU;AAAA,MACnB,OAAO;AACL,cAAM,SAAS,OAAO;AACtB,cAAM,gBAAgB,iCAAa;AAAA,UACjC;AAAA,YACE,GAAG,OAAO,OAAO;AAAA,YACjB,IAAI;AAAA,YACJ,eAAe,OAAO,iBAAiB,MAAM;AAAA,YAC7C,eAAe,OAAO,iBAAiB,IAAI;AAAA,YAC3C,aAAa,OAAO,eAAe,IAAI;AAAA,UACzC;AAAA,UACA,SAAS,eAAe;AAAA,QAC1B;AACA,YAAI,SAAS,IAAI,cAAc,IAAI,aAAa;AAChD,iBAAS,oBAAoB,KAAK,cAAc,eAAe,cAAc,EAAE;AAC/E,eAAO,UAAU;AAAA,MACnB;AAEA,UAAI,YAAY,YAAY;AAC1B,cAAM,cAAc,OAAO,OAAO;AAClC,cAAM,cAAc,IAAI,YAAY,MAAM;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,MAAyB;AACvC,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AACA,UAAM,SAAS;AACf,UAAM,OAAO,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;AAC7D,UAAM,UAA2B,CAAC;AAElC,QAAI,OAAO,OAAO,OAAO,SAAU,SAAQ,KAAK,OAAO;AACvD,QAAI,OAAO,OAAO,qBAAqB,YAAY,OAAO,qBAAqB,KAAM,SAAQ,mBAAmB,OAAO;AACvH,QAAI,OAAO,OAAO,qBAAqB,UAAW,SAAQ,mBAAmB,OAAO;AACpF,QACE,OAAO,sBAAsB,mBAC7B,OAAO,sBAAsB,gBAC7B,OAAO,sBAAsB,YAC7B;AACA,cAAQ,oBAAoB,OAAO;AAAA,IACrC;AACA,QAAI,OAAO,OAAO,kBAAkB,YAAY,OAAO,kBAAkB,KAAM,SAAQ,gBAAgB,OAAO;AAC9G,QAAI,OAAO,OAAO,uBAAuB,YAAY,OAAO,uBAAuB;AACjF,cAAQ,qBAAqB,OAAO;AACtC,QAAI,OAAO,8BAA8B,YAAY,OAAO,8BAA8B,YAAY;AACpG,cAAQ,4BAA4B,OAAO;AAAA,IAC7C;AACA,QAAI,OAAO,6BAA6B,SAAS,OAAO,6BAA6B,SAAS;AAC5F,cAAQ,2BAA2B,OAAO;AAAA,IAC5C;AACA,QAAI,OAAO,OAAO,+BAA+B,YAAY,OAAO,+BAA+B,MAAM;AACvG,cAAQ,6BAA6B,OAAO;AAAA,IAC9C;AACA,QAAI,OAAO,OAAO,oCAAoC,WAAW;AAC/D,cAAQ,kCAAkC,OAAO;AAAA,IACnD;AACA,UAAM,MAAM,IAAI,SAAS,MAAM,OAAO;AAEtC,UAAM,eAAe,OAAO,YAAY,CAAC;AACzC,QAAI,CAAC,gBAAgB,OAAO,iBAAiB,YAAY,MAAM,QAAQ,YAAY,GAAG;AACpF,YAAM,IAAI,MAAM,iEAAiE;AAAA,IACnF;AACA,eAAW,CAAC,YAAY,OAAO,KAAK,OAAO,QAAQ,YAAuC,GAAG;AAC3F,UAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C;AAAA,MACF;AACA,YAAM,SAAS,iCAAa;AAAA,QAC1B;AAAA,UACE,GAAI;AAAA,UACJ,IAAI,OAAQ,QAA6B,OAAO,WAAY,QAA2B,KAAK;AAAA,QAC9F;AAAA,QACA,SAAS,eAAe;AAAA,MAC1B;AACA,UAAI,SAAS,IAAI,OAAO,IAAI,MAAM;AAAA,IACpC;AAEA,UAAM,sBAAsB,OAAO,mBAAmB,CAAC;AACvD,QAAI,CAAC,uBAAuB,OAAO,wBAAwB,YAAY,MAAM,QAAQ,mBAAmB,GAAG;AACzG,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACjF;AACA,QAAI,gBAAgB,MAAM;AAC1B,eAAW,CAAC,SAAS,OAAO,KAAK,OAAO,QAAQ,mBAA8C,GAAG;AAC/F,UAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B;AAAA,MACF;AACA,YAAM,MAAM,QAAQ,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AACvE,UAAI,gBAAgB,IAAI,SAAS,GAAG;AAAA,IACtC;AAEA,QAAI,CAAC,OAAO,iBAAiB,OAAO,OAAO,kBAAkB,YAAY,MAAM,QAAQ,OAAO,aAAa,GAAG;AAC5G,YAAM,IAAI,MAAM,sEAAsE;AAAA,IACxF;AACA,eAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,OAAO,aAAwC,GAAG;AACjG,UAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C;AAAA,MACF;AACA,YAAM,QAAQ,2BAAU,SAAS;AAAA,QAC/B,GAAI;AAAA,QACJ,UAAU,OAAQ,QAAmC,aAAa,WAAY,QAAiC,WAAW;AAAA,MAC5H,CAAC;AACD,YAAM,YAAY;AAClB,UAAI,cAAc,IAAI,MAAM,UAAU,KAAK;AAAA,IAC7C;AAEA,QAAI,CAAC,MAAM,QAAQ,OAAO,mBAAmB,GAAG;AAC9C,YAAM,IAAI,MAAM,+EAA+E;AAAA,IACjG;AACA,UAAM,0BAA0B,OAAO;AACvC,UAAM,oBAA8B,CAAC;AACrC,eAAW,QAAQ,yBAAyB;AAC1C,UAAI,OAAO,SAAS,UAAU;AAC5B,0BAAkB,KAAK,IAAI;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,sBAAsB,kBACvB,IAAI,CAAC,aAAa,IAAI,cAAc,IAAI,QAAQ,CAAC,EACjD,OAAO,CAAC,UAA8B,QAAQ,KAAK,CAAC;AAEvD,eAAW,SAAS,IAAI,cAAc,OAAO,GAAG;AAC9C,eAAS,yBAAyB,OAAO,GAAG;AAAA,IAC9C;AAIA,QAAI,oBAAoB,MAAM;AAC9B,QAAI,kBAAkB;AACtB,QAAI,MAAM,MAAM;AAChB,QAAI,aAAa,MAAM;AAEvB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,GAAG,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;AAAA,EAC1C;AAAA,EAEA,4BAA4B,OAA0B;AACpD,UAAM,iBAAiB,MAAM,mBAAmB;AAChD,QAAI,gBAAgB;AACpB,aAAS,QAAQ,KAAK,oBAAoB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAC5E,YAAM,eAAe,KAAK,oBAAoB,KAAK;AACnD,YAAM,kBAAkB,aAAa,mBAAmB;AACxD,UAAI,gBAAgB,aAAa,eAAe,UAAU;AACxD;AAAA,MACF;AACA,WAAK,oBAAoB,OAAO,OAAO,CAAC;AACxC,uBAAiB;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,wBAAwB,UAA2B;AACjD,QAAI,KAAK,oBAAoB,IAAI,QAAQ,GAAG;AAC1C,aAAO;AAAA,IACT;AACA,eAAW,gBAAgB,KAAK,qBAAqB;AACnD,YAAM,kBAAkB,aAAa,mBAAmB;AACxD,UAAI,gBAAgB,aAAa,UAAU;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,uBAAuB,UAA2B;AAChD,WAAO,KAAK,cAAc,OAAO,QAAQ;AAAA,EAC3C;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,MAAM,GAAG,KAAK,SAAS,CAAC,8CAA8C;AAAA,IAClF;AAAA,EACF;AAAA,EAKA,QAAQ,mBAAqD,MAAqB;AAChF,UAAM,QAAQ,OAAO,qBAAqB,YAAY,qBAAqB,OAAQ,iBAAiB,SAAS,OAAQ;AACrH,QAAI,KAAK,WAAW;AAClB,UAAI,OAAO;AACT,aAAK,SAAS,MAAM;AACpB,aAAK,gBAAgB,MAAM;AAC3B,aAAK,cAAc,MAAM;AACzB,aAAK,YAAY,SAAS;AAAA,MAC5B;AACA,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,UAAM,SAAS,MAAY;AACzB,WAAK,YAAY;AACjB,WAAK,cAAc,QAAQ,IAAI;AAC/B,WAAK,kBAAkB;AACvB,iBAAW,UAAU,MAAM,KAAK,KAAK,YAAY,GAAG;AAClD,YAAI,OAAO,YAAY;AACrB,uBAAa,OAAO,UAAU;AAAA,QAChC;AACA,aAAK,aAAa,OAAO,MAAM;AAC/B,eAAO,QAAQ,IAAI;AAAA,MACrB;AACA,WAAK,oBAAoB,SAAS;AAClC,WAAK,oBAAoB,MAAM;AAC/B,WAAK,MAAM,MAAM;AACjB,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,WAAK,SAAS,MAAM;AACpB,WAAK,gBAAgB,MAAM;AAC3B,WAAK,cAAc,MAAM;AACzB,WAAK,YAAY,SAAS;AAAA,IAC5B;AACA,WAAO;AACP,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAOA,GACE,eACA,SACA,UAAiC,CAAC,GACpB;AACd,SAAK,kBAAkB;AACvB,UAAM,qBAAiB,oCAAsB,aAAa;AAC1D,UAAM,eAAe,iCAAa,wBAAwB,OAA+B;AACzF,UAAM,gBAAgB,IAAI,iCAAa;AAAA,MACrC;AAAA,MACA;AAAA,MACA,2BAAuB,kCAAkB;AAAA,MACzC,eAAe;AAAA,MACf,eAAe,KAAK;AAAA,MACpB,aAAa,KAAK;AAAA,MAClB,GAAG;AAAA,IACL,CAAC;AACD,QAAI,KAAK,iCAAiC;AAGxC,oBAAc,uBAAuB;AAAA,IACvC;AAEA,SAAK,SAAS,IAAI,cAAc,IAAI,aAAa;AACjD,UAAM,MAAM,KAAK,gBAAgB,IAAI,cAAc,aAAa;AAChE,QAAI,IAAK,KAAI,KAAK,cAAc,EAAE;AAAA,QAC7B,MAAK,gBAAgB,IAAI,cAAc,eAAe,CAAC,cAAc,EAAE,CAAC;AAC7E,SAAK,kBAAkB,MAAM;AAC3B,WAAK,KAAK,qBAAqB,eAAe,IAAI;AAAA,IACpD,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,IAAyB,eAAsC,SAAiE;AAC9H,SAAK,kBAAkB;AACvB,UAAM,qBAAiB,oCAAsB,aAAa;AAC1D,QAAI,OAAO,YAAY,YAAY,mBAAmB,oCAAgB,QAAQ,OAAO,QAAW;AAC9F,gBAAU,QAAQ;AAAA,IACpB;AACA,UAAM,cAAc,OAAO,YAAY;AACvC,eAAW,SAAS,KAAK,SAAS,OAAO,GAAG;AAC1C,UAAI,MAAM,kBAAkB,gBAAgB;AAC1C;AAAA,MACF;AACA,YAAM,aAAa,MAAM;AACzB,UAAI,YAAY,WAAc,cAAc,eAAe,UAAU,MAAM,YAAa,UAAmC;AACzH,aAAK,SAAS,OAAO,UAAU;AAC/B,aAAK,sBAAsB,MAAM,eAAe,UAAU;AAC1D,aAAK,kBAAkB,MAAM;AAC3B,eAAK,KAAK,qBAAqB,OAAO,KAAK;AAAA,QAC7C,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAA0B,OAAa;AACrC,SAAK,kBAAkB;AACvB,UAAM,iBAAiB,MAAM,mBAAmB;AAChD,UAAM,iBAAiB,KAAK,MAAM,iDAAiD;AACnF,QACE,kBACA,eAAe,WAAW,aAC1B,eAAe,WAAW,cACzB,eAAe,iBAAiB,gDAC/B,eAAe,iBAAiB,kDAChC,eAAe,iBAAiB,+CAClC;AACA,aAAO;AAAA,IACT;AACA,QAAI,CAAC,eAAe,WAAW;AAE7B,qBAAe,YAAY;AAAA,IAC7B;AACA,QAAI,CAAC,MAAM,QAAQ,eAAe,UAAU,GAAG;AAC7C,qBAAe,aAAa,CAAC;AAAA,IAC/B;AACA,QAAI,eAAe,oBAAoB,MAAM,QAAW;AAItD,qBAAe,wBAAoB,0CAAoB,CAAC;AAAA,IAC1D;AACA,QAAI,eAAe,WAAW,SAAS,KAAK,KAAK,KAAK,KAAK,mBAAmB,cAAc,GAAG;AAC7F,aAAO,KAAK,8BAA8B,cAAc;AAAA,IAC1D;AAEA,QAAI,CAAC,eAAe,WAAW,SAAS,KAAK,KAAK,GAAG;AACnD,qBAAe,WAAW,KAAK,KAAK,KAAK;AAAA,IAC3C;AAEA,QAAI,eAAe,mBAAmB,eAAe,6BAA6B;AAChF,YAAM,gBAAgB,eAAe,cAAc,cAAc,IAAI,eAAe,2BAA2B;AAC/G,UAAI,eAAe;AACjB,sBAAc,uBAAuB,cAAc;AAAA,MACrD;AAAA,IACF;AAEA,QACE,KAAK,cAAc,qBAAqB,QACxC,KAAK,cAAc,mBAAmB,KACtC,CAAC,KAAK,cAAc,oBACpB,KAAK,cAAc,QAAQ,KAAK,cAAc,kBAC9C;AACA,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,SAAS,CAAC,SAAS,eAAe,UAAU,sCAAsC,KAAK,cAAc,IAAI,IAAI,KAAK,cAAc,gBAAgB;AAAA,MAC1J;AAAA,IACF;AAEA,SAAK,cAAc,SAAS,cAAc;AAC1C,SAAK,cAAc,iBAAiB;AAAA,MAClC,mBAAmB,CAAC,oBAAoB,gBAAgB,iBAAiB;AAAA,MACzE,WAAW,CAAC,oBAAoB,gBAAgB,IAAI;AAAA,MACpD,aAAa,KAAK,SAAS;AAAA,MAC3B,kBAAkB,KAAK,cAAc;AAAA,MACrC,kBAAkB,KAAK,cAAc;AAAA,IACvC,CAAC;AACD,SAAK,oBAAoB,cAAc;AAEvC,mBAAe,2BAA2B;AAC1C,SAAK,oBAAoB,KAAK,cAAc;AAC5C,QAAI,KAAK,MAAM,gBAAgB,cAAc,MAAM,MAAM;AACvD,WAAK,iCAAiC,cAAc;AAAA,IACtD,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AAEA,WAAO,KAAK,8BAA8B,cAAc;AAAA,EAC1D;AAAA;AAAA,EAGA,SAA8B,OAAa;AACzC,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AAAA,EAOA,MAAM,KACJ,eACA,mBAA6D,CAAC,GAC9D,gBAAgC,CAAC,GACd;AACnB,UAAM,QAAQ,OAAO,qBAAqB,aAAa,mBAAmB,MAAM;AAChF,UAAM,UAAU,OAAO,qBAAqB,aAAa,gBAAgB;AAEzE,QAAI,kBAAkB;AACtB,QAAI,oBAAoC;AACxC,QAAI,OAAO,UAAU,eAAe,KAAK,SAAS,OAAO,GAAG;AAC1D,YAAM,EAAE,OAAO,mBAAmB,GAAG,KAAK,IAAI;AAC9C,YAAM,cAAc;AACpB,wBAAkB,CAAC,UAAc,MAA6C,UAAU,qBAAqB,YAAY,KAAK;AAC9H,0BAAoB;AAAA,IACtB;AACA,UAAM,UAAU,MAAM,KAAK,OAAO,eAAwC,iBAAiB,EAAE,GAAG,mBAAmB,OAAO,EAAE,CAAC;AAC7H,WAAO,QAAQ,SAAS,IAAI,QAAQ,CAAC,IAAI;AAAA,EAC3C;AAAA,EAQA,MAAM,OACJ,eACA,mBAA+D,CAAC,GAChE,gBAAkC,CAAC,GACrB;AACd,SAAK,kBAAkB;AACvB,UAAM,QAAQ,OAAO,qBAAqB,aAAa,mBAAmB,MAAM;AAChF,UAAM,UAAU,OAAO,qBAAqB,aAAa,gBAAgB;AACzE,UAAM,UAAU,MAAM,KAAK,cAAc,OAAO,eAAwC,OAAO;AAAA,MAC7F,GAAG;AAAA,MACH,mBAAmB,CAAC,OAAO,aAAa,KAAK,eAAe,OAAO,QAAQ;AAAA,MAC3E,uBAAuB,CAAC,0BAA0B,YAAY,WAC5D,KAAK,oBAAoB,0BAA0B,YAAY,MAAM;AAAA,IACzE,CAAC;AACD,WAAO,QAAQ,IAAI,CAAC,UAAU,KAAK,8BAA8B,KAAK,CAAM;AAAA,EAC9E;AAAA,EAEA,MAAc,oBACZ,eACA,SACA,QAC2B;AAC3B,QAAI,WAAW,OAAO;AACpB,aAAO;AAAA,IACT;AACA,WAAO,MAAM,IAAI,QAA0B,CAAC,YAAY;AACtD,YAAM,SAAoC;AAAA,QACxC;AAAA,QACA;AAAA,QACA,SAAS,CAAC,UAAU,QAAQ,KAAK;AAAA,MACnC;AACA,UAAI,WAAW,MAAM;AACnB,cAAM,aAAa,KAAK,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI;AACjD,eAAO,aAAa,WAAW,MAAM;AACnC,eAAK,aAAa,OAAO,MAAM;AAC/B,kBAAQ,IAAI;AAAA,QACd,GAAG,UAAU;AAAA,MACf;AACA,WAAK,aAAa,IAAI,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,UAAyB,MAAwB;AACnE,SAAK,kBAAkB;AACvB,WAAO,MAAM,KAAK,MAAM,YAAY,OAAO;AAAA,EAC7C;AAAA;AAAA,EAGA,SAAkB;AAChB,eAAW,SAAS,KAAK,cAAc,OAAO,GAAG;AAC/C,iBAAW,UAAU,MAAM,cAAc,OAAO,GAAG;AACjD,YAAI,OAAO,gBAAgB,KAAK,IAAI;AAClC;AAAA,QACF;AACA,YAAI,OAAO,WAAW,aAAa,OAAO,WAAW,WAAW;AAC9D,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,sBAA+B;AAC7B,WAAO,KAAK,oBAAoB,WAAW,KAAK,KAAK,oBAAoB,SAAS,KAAK,KAAK,OAAO,KAAK,CAAC,KAAK;AAAA,EAChH;AAAA,EAEA,eAAe,aAAwB,cAAkC;AACvE,QAAI,YAAY,aAAa,aAAa,UAAU;AAClD,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB,YAAY;AACpC,WAAO,mBAAmB;AACxB,UAAI,sBAAsB,aAAa,UAAU;AAC/C,eAAO;AAAA,MACT;AACA,YAAM,SAAS,KAAK,cAAc,IAAI,iBAAiB;AACvD,UAAI,CAAC,QAAQ;AACX,eAAO;AAAA,MACT;AACA,0BAAoB,OAAO;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,cAAyB,aAAiC;AACxE,WAAO,KAAK,eAAe,aAAa,YAAY;AAAA,EACtD;AAAA;AAAA,EAGA,UAAkB;AAChB,eAAO,wBAAQ,IAAI;AAAA,EACrB;AAAA;AAAA,EAGA,cAAc,UAAoC;AAChD,WAAO,KAAK,cAAc,IAAI,QAAQ,KAAK,KAAK,cAAc,cAAc,QAAQ;AAAA,EACtF;AAAA,EAEQ,gBAAsB;AAC5B,SAAK,kBAAkB;AACvB,QAAI,KAAK,iBAAiB;AACxB;AAAA,IACF;AACA,SAAK,kBAAkB;AACvB,SAAK,kBAAkB,MAAM;AAC3B,WAAK,KAAK,SAAS;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEQ,iCAAiC,OAAwB;AAC/D,QAAI,KAAK,oBAAoB,IAAI,MAAM,QAAQ,GAAG;AAChD;AAAA,IACF;AACA,UAAM,cAAc,KAAK,oBAAoB,QAAQ,KAAK;AAC1D,QAAI,eAAe,GAAG;AACpB,WAAK,oBAAoB,OAAO,aAAa,CAAC;AAAA,IAChD,WAAW,MAAM,iBAAiB,aAAa;AAC7C;AAAA,IACF;AACA,SAAK,oBAAoB,IAAI,MAAM,QAAQ;AAC3C,SAAK,kBAAkB,MAAM;AAC3B,WAAK,KAAK,cAAc,KAAK;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,MAAc,cACZ,OACA,UAGI,CAAC,GACU;AACf,QAAI,kBAGC,CAAC;AACN,QAAI;AACF,UAAI,KAAK,mBAAmB,KAAK,GAAG;AAClC;AAAA,MACF;AACA,YAAM,eAAe,KAAK,8BAA8B,KAAK;AAC7D,YAAM,KAAK,eAAe,cAAc,SAAS;AACjD,YAAM,aAAa;AACnB,wBAAkB,MAAM,6BAA6B,IAAI;AACzD,YAAM,yBAAyB,MAAM,iBAAiB,KAAK;AAC3D,YAAM,8BAA8B,MAAM,sBAAsB,KAAK;AACrE,UAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,mBAAW,SAAS,iBAAiB;AACnC,gBAAM,KAAK,qBAAqB,cAAc,MAAM,QAAQ,SAAS;AAAA,QACvE;AAAA,MACF;AACA,YAAM,KAAK,MAAM;AAAA,QACf;AAAA,QACA,MACE,KAAK;AAAA,UAAwB;AAAA,UAAO;AAAA,UAAiB;AAAA,UAAwB,UAC3E;AAAA,YAAoB,MAAM,6BAA6B,6BAA6B,KAAK,IAAI;AAAA,YAAG,MAC9F,aAAa,aAAa,eAAe;AAAA,UAC3C;AAAA,QACF;AAAA,QACF;AAAA,MACF;AACA,WAAK,4BAA4B,KAAK;AAAA,IACxC,UAAE;AACA,UAAI,QAAQ,mBAAmB;AAC7B,gBAAQ,kBAAkB,QAAQ;AAAA,MACpC;AACA,WAAK,oBAAoB,OAAO,MAAM,QAAQ;AAC9C,WAAK,MAAM,qBAAqB;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,yBAA8C,OAAU,gBAA0C;AACtG,UAAM,iBAAiB,MAAM,mBAAmB;AAIhD,UAAM,eAAe,gBAAgB,WAAW,YAAY,iBAAiB;AAC7E,UAAM,gCAAgC,gBAAgB,KAAK,MAAM,8CAA8C;AAC/G,QAAI,CAAC,+BAA+B;AAClC,YAAM,cAAc,KAAK,oBAAoB,QAAQ,cAAc;AACnE,YAAM,aAAa,KAAK,MAAM,gBAAgB,cAAc;AAC5D,YAAM,kCACJ,gBAAgB,KAChB,CAAC,KAAK,MAAM,UAAU,KACtB,CAAC,KAAK,oBAAoB,IAAI,eAAe,QAAQ,KACrD,CAAC,KAAK,mBAAmB,cAAc,MACtC,eAAe,QAAQ,WAAW,WAAW;AAChD,UAAI,iCAAiC;AACnC,YAAI,oBAAsC;AAC1C,YAAI,YAAY;AACd,gBAAM,WAAW,QAAQ;AACzB,8BAAoB;AAAA,QACtB;AACA,cAAM,aAAa,KAAK,oBAAoB,CAAC;AAC7C,cAAM,sBAAsB,YAAY,mBAAmB;AAC3D,YACE,wBAAwB,kBACxB,CAAC,KAAK,MAAM,UAAU,KACtB,CAAC,KAAK,oBAAoB,IAAI,eAAe,QAAQ,KACrD,CAAC,KAAK,mBAAmB,cAAc,GACvC;AACA,eAAK,oBAAoB,MAAM;AAC/B,eAAK,oBAAoB,IAAI,eAAe,QAAQ;AACpD,gBAAM,KAAK,cAAc,gBAAgB;AAAA,YACvC,oBAAoB;AAAA,YACpB;AAAA,UACF,CAAC;AACD,cAAI,eAAe,iBAAiB,aAAa;AAC/C,kBAAM,KAAK,oCAAoC,cAAc;AAAA,UAC/D;AACA,iBAAO;AAAA,QACT;AACA,2BAAmB,QAAQ;AAAA,MAC7B;AACA,YAAM,KAAK,oCAAoC,cAAc;AAC7D,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,8BAA8B,MAAM,mBAAmB,8BAA8B;AAC3G,UAAM,6BACJ,eAAe,oBAAoB,cAAc,YACjD,eAAe,gCAAgC,8BAA8B,cAC7E,8BAA8B,eAAe,KAAK,CAAC,WAAW,MAAM,mBAAmB,OAAO,aAAa,eAAe,QAAQ;AACpI,QAAI,4BAA4B;AAC9B,qBAAe,iCAAiC;AAAA,IAClD;AAMA,QAAI,KAAK,MAAM,gBAAgB,cAAc,MAAM,MAAM;AACvD,oCAA8B,sBAAsB,IAAI;AAAA,IAC1D;AACA,QAAI,eAAe,iBAAiB,aAAa;AAC/C,aAAO;AAAA,IACT;AAGA,QAAI,8BAA8B,OAAO;AACvC,YAAM,8BAA8B,MAAM,aAAa,KAAK,oCAAoC,KAAK,MAAM,cAAc,CAAC;AAC1H,aAAO;AAAA,IACT;AAEA,UAAM,KAAK,oCAAoC,cAAc;AAC7D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,MAAc,oCAAoC,OAAiC;AAGjF,UAAM,wBAAwB,KAAK,MAAM,gBAAgB,KAAK;AAE9D,eAAS;AAKP,YAAM,UAAsB,CAAC;AAC7B,YAAM,OAAO,oBAAI,IAAc;AAC/B,YAAM,aAAa,MAAM,QAAQ,MAAM,UAAU,IAAI,MAAM,aAAa,CAAC;AACzE,iBAAW,SAAS,YAAY;AAC9B,mBAAW,OAAO,KAAK,eAAe;AACpC,cAAI,IAAI,UAAU,OAAO;AACvB;AAAA,UACF;AACA,cAAI,CAAC,IAAI,cAAc,IAAI,MAAM,QAAQ,GAAG;AAC1C;AAAA,UACF;AACA,cAAI,IAAI,mBAAmB,KAAK,GAAG;AACjC;AAAA,UACF;AACA,cAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,oBAAQ,KAAK,GAAG;AAChB,iBAAK,IAAI,GAAG;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,cAAc,IAAI,MAAM,QAAQ,KAAK,CAAC,KAAK,mBAAmB,KAAK,GAAG;AAChG,gBAAQ,KAAK,IAAI;AAAA,MACnB;AAEA,YAAM,iBAAoC,CAAC;AAC3C,UAAI,gBAAgB;AACpB,UAAI;AACF,mBAAW,OAAO,SAAS;AACzB,cAAI,QAAQ,MAAM;AAChB,2BAAe,KAAK,IAAI,MAAM,qBAAqB,CAAC;AAAA,UACtD;AAAA,QACF;AAEA,mBAAW,OAAO,SAAS;AACzB,gBAAM,QAAQ,IAAI,oBAAoB,QAAQ,KAAK;AACnD,cAAI,SAAS,GAAG;AACd,gBAAI,oBAAoB,OAAO,OAAO,CAAC;AAAA,UACzC;AACA,cAAI,IAAI,mBAAmB,KAAK,GAAG;AACjC;AAAA,UACF;AACA,cAAI,IAAI,oBAAoB,IAAI,MAAM,QAAQ,GAAG;AAC/C;AAAA,UACF;AACA,cAAI,oBAAoB,IAAI,MAAM,QAAQ;AAC1C,0BAAgB;AAKhB,gBAAM,iBAAiB,IAAI,MAAM,gBAAgB,KAAK;AACtD,gBAAM,2BAA2B,QAAQ,QAAS,0BAA0B,QAAQ,mBAAmB;AAEvG,gBAAM,IAAI,cAAc,OAAO;AAAA,YAC7B,oBAAoB;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF,UAAE;AACA,mBAAW,WAAW,gBAAgB;AACpC,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI,MAAM,iBAAiB,aAAa;AACtC;AAAA,MACF;AACA,UAAI,CAAC,eAAe;AAClB,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,WAA0B;AACtC,eAAS;AACP,aAAO,KAAK,oBAAoB,SAAS,GAAG;AAC1C,cAAM,QAAQ,QAAQ;AACtB,YAAI,KAAK,MAAM,UAAU,GAAG;AAC1B,gBAAM,KAAK,MAAM,yBAAyB;AAC1C;AAAA,QACF;AACA,cAAM,aAAa,KAAK,oBAAoB,CAAC;AAC7C,YAAI,CAAC,YAAY;AACf;AAAA,QACF;AACA,cAAM,iBAAiB,WAAW,mBAAmB;AACrD,YAAI,KAAK,mBAAmB,cAAc,GAAG;AAC3C,eAAK,oBAAoB,MAAM;AAC/B;AAAA,QACF;AACA,YAAI,oBAAsC;AAC1C,cAAM,aAAa,KAAK,MAAM,gBAAgB,cAAc;AAC5D,YAAI,YAAY;AACd,gBAAM,WAAW,QAAQ;AACzB,8BAAoB;AAAA,QACtB;AAIA,cAAM,eAAe,KAAK,oBAAoB,CAAC;AAC/C,cAAM,wBAAwB,cAAc,mBAAmB;AAC/D,YAAI,0BAA0B,gBAAgB;AAC5C,cAAI,mBAAmB;AACrB,8BAAkB,QAAQ;AAAA,UAC5B;AACA;AAAA,QACF;AACA,aAAK,oBAAoB,MAAM;AAC/B,YAAI,KAAK,oBAAoB,IAAI,eAAe,QAAQ,GAAG;AACzD,cAAI,mBAAmB;AACrB,8BAAkB,QAAQ;AAAA,UAC5B;AACA;AAAA,QACF;AACA,aAAK,oBAAoB,IAAI,eAAe,QAAQ;AACpD,aAAK,KAAK,cAAc,gBAAgB;AAAA,UACtC,oBAAoB;AAAA,UACpB;AAAA,QACF,CAAC;AACD,cAAM,QAAQ,QAAQ;AAAA,MACxB;AACA,WAAK,kBAAkB;AACvB,UAAI,KAAK,oBAAoB,SAAS,GAAG;AACvC,aAAK,cAAc;AACnB;AAAA,MACF;AACA,WAAK,MAAM,qBAAqB;AAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,mBAAmB,OAA2B;AAC5C,UAAM,UAAU,MAAM,KAAK,MAAM,cAAc,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,OAAO,gBAAgB,KAAK,EAAE;AAC1G,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,MAAM,CAAC,WAAW,OAAO,WAAW,eAAe,OAAO,WAAW,OAAO;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA,EAKA,8BAAmD,OAAU,gBAAiC;AAC5F,UAAM,iBAAiB,MAAM,mBAAmB;AAChD,UAAM,MAAM;AACZ,UAAM,kBAAkB,eAAe;AACvC,UAAM,YAAY,IAAI,MAAM,KAAK;AAAA,MAC/B,IAAI,QAAQ,MAAM,UAAU;AAC1B,YAAI,SAAS,4BAA4B;AACvC,gBAAM,SAAS,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AACjD,gBAAM,4BAA4B,CAA2B,gBAAyC;AACpG,mBAAO,OAAO,KAAK,QAAQ,aAAa,cAAc;AAAA,UACxD;AACA,iBAAO;AAAA,QACT;AACA,YAAI,SAAS,cAAc,SAAS,QAAQ;AAC1C,gBAAM,mBAAmB,CAA2B,gBAAgC;AAClF,kBAAM,iBAAiB,YAAY,mBAAmB;AACtD,kBAAM,6BAA6B,kBAAkB,eAAe,WAAW,aAAa,eAAe,WAAW;AACtH,gBACE,+BACC,eAAe,iBAAiB,gDAC/B,eAAe,iBAAiB,kDAChC,eAAe,iBAAiB,+CAClC;AACA,qBAAO;AAAA,YACT;AACA,gBAAI,kBAAkB,CAAC,4BAA4B;AACjD,6BAAe,uBAAuB,cAAc;AAAA,YACtD,WAAW,CAAC,eAAe,mBAAmB,eAAe,aAAa,iBAAiB;AAEzF,6BAAe,kBAAkB;AAAA,YACnC;AACA,kBAAM,aAAa,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AACrD,kBAAM,aAAa,WAAW,KAAK,QAAQ,cAAc;AACzD,mBAAO,OAAO,8BAA8B,YAAsB,cAAc;AAAA,UAClF;AACA,iBAAO;AAAA,QACT;AACA,eAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF,CAAC;AACD,UAAM,SAAS,IAAI,MAAM,gBAAgB;AAAA,MACvC,IAAI,QAAQ,MAAM,UAAU;AAC1B,YAAI,SAAS,aAAa;AACxB,iBAAO;AAAA,QACT;AACA,YAAI,SAAS,mBAAmB;AAC9B,iBAAO;AAAA,QACT;AACA,eAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,MAC3C;AAAA,MACA,IAAI,QAAQ,MAAM,OAAO;AACvB,YAAI,SAAS,aAAa;AACxB,iBAAO;AAAA,QACT;AACA,eAAO,QAAQ,IAAI,QAAQ,MAAM,OAAO,MAAM;AAAA,MAChD;AAAA,MACA,IAAI,QAAQ,MAAM;AAChB,YAAI,SAAS,aAAa;AACxB,iBAAO;AAAA,QACT;AACA,YAAI,SAAS,mBAAmB;AAC9B,iBAAO;AAAA,QACT;AACA,eAAO,QAAQ,IAAI,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,OAAwB;AAClD,eAAW,UAAU,MAAM,KAAK,KAAK,YAAY,GAAG;AAClD,UAAK,OAAO,kBAAkB,OAAO,MAAM,eAAe,OAAO,iBAAkB,CAAC,OAAO,QAAQ,KAAK,GAAG;AACzG;AAAA,MACF;AACA,UAAI,OAAO,YAAY;AACrB,qBAAa,OAAO,UAAU;AAAA,MAChC;AACA,WAAK,aAAa,OAAO,MAAM;AAC/B,aAAO,QAAQ,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,qBAAqB,OAAkC;AACrD,UAAM,WAA2B,CAAC;AAClC,eAAW,OAAO,CAAC,MAAM,YAAY,GAAG,GAAG;AACzC,YAAM,MAAM,KAAK,gBAAgB,IAAI,GAAG;AACxC,UAAI,CAAC,IAAK;AACV,iBAAW,MAAM,KAAK;AACpB,cAAM,QAAQ,KAAK,SAAS,IAAI,EAAE;AAClC,YAAI,MAAO,UAAS,KAAK,KAAK;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,eAA6B,YAA0B;AACnF,UAAM,MAAM,KAAK,gBAAgB,IAAI,aAAa;AAClD,QAAI,CAAC,IAAK;AACV,UAAM,MAAM,IAAI,QAAQ,UAAU;AAClC,QAAI,MAAM,EAAG;AACb,QAAI,OAAO,KAAK,CAAC;AACjB,QAAI,IAAI,WAAW,EAAG,MAAK,gBAAgB,OAAO,aAAa;AAAA,EACjE;AACF;",
6
6
  "names": ["uuidv7"]
7
7
  }
@@ -5,7 +5,7 @@ import type { EventResult } from './EventResult.js';
5
5
  export type EphemeralFindEventHandler = {
6
6
  event_pattern: string | '*';
7
7
  matches: (event: BaseEvent) => boolean;
8
- resolve: (event: BaseEvent) => void;
8
+ resolve: (event: BaseEvent | null) => void;
9
9
  timeout_id?: ReturnType<typeof setTimeout>;
10
10
  };
11
11
  export declare const FindWaiterJSONSchema: z.ZodObject<{
@@ -17,12 +17,12 @@ export declare class FindWaiter {
17
17
  static toJSON(waiter: EphemeralFindEventHandler): FindWaiterJSON;
18
18
  static fromJSON(data: unknown, overrides?: {
19
19
  matches?: (event: BaseEvent) => boolean;
20
- resolve?: (event: BaseEvent) => void;
20
+ resolve?: (event: BaseEvent | null) => void;
21
21
  }): EphemeralFindEventHandler;
22
22
  static toJSONArray(waiters: Iterable<EphemeralFindEventHandler>): FindWaiterJSON[];
23
23
  static fromJSONArray(data: unknown, overrides?: {
24
24
  matches?: (event: BaseEvent) => boolean;
25
- resolve?: (event: BaseEvent) => void;
25
+ resolve?: (event: BaseEvent | null) => void;
26
26
  }): EphemeralFindEventHandler[];
27
27
  }
28
28
  export declare const EventHandlerJSONSchema: z.ZodObject<{
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/EventHandler.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport { v5 as uuidv5 } from 'uuid'\n\nimport { normalizeEventPattern, type EventHandlerCallable, type EventPattern } from './types.js'\nimport { BaseEvent } from './BaseEvent.js'\nimport type { EventResult } from './EventResult.js'\nimport { monotonicDatetime } from './helpers.js'\n\nconst HANDLER_ID_NAMESPACE = uuidv5('abxbus-handler', uuidv5.DNS)\nconst BOUND_FUNCTION_PREFIX = 'bound '\n\nconst normalizeCallableName = (name: string | undefined): string => {\n if (!name) {\n return 'anonymous'\n }\n if (name.startsWith(BOUND_FUNCTION_PREFIX) && name.length > BOUND_FUNCTION_PREFIX.length) {\n return name.slice(BOUND_FUNCTION_PREFIX.length)\n }\n return name\n}\n\nexport type EphemeralFindEventHandler = {\n // Similar to a handler, except it's for .find() calls.\n // Resolved on dispatch, ephemeral, and never shows up in the processing tree.\n event_pattern: string | '*'\n matches: (event: BaseEvent) => boolean\n resolve: (event: BaseEvent) => void\n timeout_id?: ReturnType<typeof setTimeout>\n}\n\nexport const FindWaiterJSONSchema = z\n .object({\n event_pattern: z.union([z.string(), z.literal('*')]),\n has_timeout: z.boolean(),\n })\n .strict()\n\nexport type FindWaiterJSON = z.infer<typeof FindWaiterJSONSchema>\n\nexport class FindWaiter {\n static toJSON(waiter: EphemeralFindEventHandler): FindWaiterJSON {\n return {\n event_pattern: waiter.event_pattern,\n has_timeout: waiter.timeout_id !== undefined,\n }\n }\n\n static fromJSON(\n data: unknown,\n overrides: {\n matches?: (event: BaseEvent) => boolean\n resolve?: (event: BaseEvent) => void\n } = {}\n ): EphemeralFindEventHandler {\n const record = FindWaiterJSONSchema.parse(data)\n const event_pattern = record.event_pattern\n const defaultMatches = (event: BaseEvent): boolean => event_pattern === '*' || event.event_type === event_pattern\n return {\n event_pattern,\n matches: overrides.matches ?? defaultMatches,\n resolve: overrides.resolve ?? (() => {}),\n }\n }\n\n static toJSONArray(waiters: Iterable<EphemeralFindEventHandler>): FindWaiterJSON[] {\n return Array.from(waiters, (waiter) => FindWaiter.toJSON(waiter))\n }\n\n static fromJSONArray(\n data: unknown,\n overrides: {\n matches?: (event: BaseEvent) => boolean\n resolve?: (event: BaseEvent) => void\n } = {}\n ): EphemeralFindEventHandler[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.map((item) => FindWaiter.fromJSON(item, overrides))\n }\n}\n\nexport const EventHandlerJSONSchema = z\n .object({\n id: z.string(),\n eventbus_name: z.string(),\n eventbus_id: z.string().uuid(),\n event_pattern: z.union([z.string(), z.literal('*')]),\n handler_name: z.string(),\n handler_file_path: z.string().nullable().optional(),\n handler_timeout: z.number().nullable().optional(),\n handler_slow_timeout: z.number().nullable().optional(),\n handler_registered_at: z.string().datetime(),\n })\n .strict()\n\nexport type EventHandlerJSON = z.infer<typeof EventHandlerJSONSchema>\n\n// an entry in the list of event handlers that are registered on a bus\nexport class EventHandler {\n id: string // unique uuidv5 based on hash of bus name, handler name, handler file path:lineno, registered at timestamp, and event key\n handler: EventHandlerCallable // original callable passed to on()\n handler_name: string // name of the handler function, or 'anonymous' if the handler is an anonymous/arrow function\n handler_file_path: string | null // ~/path/to/source/file.ts:123, or null when unknown\n handler_timeout?: number | null // maximum time in seconds that the handler is allowed to run before it is aborted, resolved at runtime if not set\n handler_slow_timeout?: number | null // warning threshold in seconds for slow handler execution\n handler_registered_at: string // ISO datetime used in the deterministic handler-id seed\n event_pattern: string | '*' // event_type string to match against, or '*' to match all events\n eventbus_name: string // name of the event bus that the handler is registered on\n eventbus_id: string // uuidv7 identifier of the event bus that the handler is registered on\n\n constructor(params: {\n id?: string\n handler: EventHandlerCallable\n handler_name: string\n handler_file_path?: string | null\n handler_timeout?: number | null\n handler_slow_timeout?: number | null\n handler_registered_at: string\n event_pattern: string | '*'\n eventbus_name: string\n eventbus_id: string\n }) {\n const handler_registered_at = monotonicDatetime(params.handler_registered_at)\n this.id =\n params.id ??\n EventHandler.computeHandlerId({\n eventbus_id: params.eventbus_id,\n handler_name: params.handler_name,\n handler_file_path: params.handler_file_path,\n handler_registered_at,\n event_pattern: params.event_pattern,\n })\n this.handler = params.handler\n this.handler_name = params.handler_name\n this.handler_file_path = params.handler_file_path ?? null\n this.handler_timeout = params.handler_timeout\n this.handler_slow_timeout = params.handler_slow_timeout\n this.handler_registered_at = handler_registered_at\n this.event_pattern = params.event_pattern\n this.eventbus_name = params.eventbus_name\n this.eventbus_id = params.eventbus_id\n }\n\n get _handler_async(): EventHandlerCallable {\n const handler = this.handler\n if (Object.prototype.toString.call(handler) === '[object AsyncFunction]') {\n return handler\n }\n return async (event: BaseEvent) => await handler(event)\n }\n\n static handlerNameFromCallable(handler: EventHandlerCallable): string {\n return normalizeCallableName(handler.name)\n }\n\n // compute globally unique handler uuid as a hash of the bus name, handler name, handler file path, registered at timestamp, and event key\n static computeHandlerId(params: {\n eventbus_id: string\n handler_name: string\n handler_file_path?: string | null\n handler_registered_at: string\n event_pattern: string | '*'\n }): string {\n const file_path = params.handler_file_path ?? 'unknown'\n const seed = `${params.eventbus_id}|${params.handler_name}|${file_path}|${params.handler_registered_at}|${params.event_pattern}`\n return uuidv5(seed, HANDLER_ID_NAMESPACE)\n }\n\n static fromCallable<TEvent extends BaseEvent = BaseEvent>(params: {\n handler: EventHandlerCallable<TEvent>\n event_pattern: EventPattern | '*'\n eventbus_name: string\n eventbus_id: string\n detect_handler_file_path?: boolean\n id?: string\n handler_file_path?: string | null\n handler_timeout?: number | null\n handler_slow_timeout?: number | null\n handler_registered_at?: string\n }): EventHandler {\n const entry = new EventHandler({\n id: params.id,\n handler: params.handler as EventHandlerCallable,\n handler_name: EventHandler.handlerNameFromCallable(params.handler as EventHandlerCallable),\n handler_file_path: params.handler_file_path ?? null,\n handler_timeout: params.handler_timeout,\n handler_slow_timeout: params.handler_slow_timeout,\n handler_registered_at: monotonicDatetime(params.handler_registered_at),\n event_pattern: normalizeEventPattern(params.event_pattern),\n eventbus_name: params.eventbus_name,\n eventbus_id: params.eventbus_id,\n })\n const should_detect_handler_file_path = params.detect_handler_file_path ?? true\n if (should_detect_handler_file_path && entry.handler_file_path === null) {\n entry._detectHandlerFilePath()\n if (params.id === undefined) {\n entry.id = EventHandler.computeHandlerId({\n eventbus_id: entry.eventbus_id,\n handler_name: entry.handler_name,\n handler_file_path: entry.handler_file_path,\n handler_registered_at: entry.handler_registered_at,\n event_pattern: entry.event_pattern,\n })\n }\n }\n return entry\n }\n\n // \"someHandlerName() @ ~/path/to/source/file.ts:123\" <- best case when file path is available and its a named function\n // \"function#1234()\" <- worst case when no file path is available and its an anonymous/arrow function defined inline\n toString(): string {\n const label = this.handler_name && this.handler_name !== 'anonymous' ? `${this.handler_name}()` : `function#${this.id.slice(-4)}()`\n return this.handler_file_path ? `${label} @ ${this.handler_file_path}` : label\n }\n\n // autodetect the path/to/source/file.ts:lineno where the handler is defined for better logs\n // optional (controlled by EventBus.event_handler_detect_file_paths) because it can slow down performance to introspect stack traces and find file paths\n _detectHandlerFilePath(): void {\n const line = new Error().stack\n ?.split('\\n')\n .map((l) => l.trim())\n .filter(Boolean)[4]\n if (!line) return\n const resolved_path =\n line.trim().match(/\\(([^)]+)\\)$/)?.[1] ??\n line.trim().match(/^\\s*at\\s+(.+)$/)?.[1] ??\n line.trim().match(/^[^@]+@(.+)$/)?.[1] ??\n line.trim()\n const match = resolved_path.match(/^(.*?):(\\d+)(?::\\d+)?$/)\n let normalized = match ? match[1] : resolved_path\n const line_number = match?.[2]\n if (normalized.startsWith('file://')) {\n let path = normalized.slice('file://'.length)\n if (path.startsWith('localhost/')) path = path.slice('localhost'.length)\n if (!path.startsWith('/')) path = `/${path}`\n try {\n normalized = decodeURIComponent(path)\n } catch {\n normalized = path\n }\n }\n normalized = normalized.replace(/\\/users\\/[^/]+\\//i, '~/').replace(/\\/home\\/[^/]+\\//i, '~/')\n this.handler_file_path = line_number ? `${normalized}:${line_number}` : normalized\n }\n\n toJSON(): EventHandlerJSON {\n return {\n id: this.id,\n eventbus_name: this.eventbus_name,\n eventbus_id: this.eventbus_id,\n event_pattern: this.event_pattern,\n handler_name: this.handler_name,\n handler_file_path: this.handler_file_path,\n handler_timeout: this.handler_timeout,\n handler_slow_timeout: this.handler_slow_timeout,\n handler_registered_at: this.handler_registered_at,\n }\n }\n\n static fromJSON(data: unknown, handler?: EventHandlerCallable): EventHandler {\n const record = EventHandlerJSONSchema.parse(data)\n const handler_fn = handler ?? ((() => undefined) as EventHandlerCallable)\n const handler_name = record.handler_name || handler_fn.name || 'anonymous' // 'anonymous' is the default name for anonymous/arrow functions\n return new EventHandler({\n id: record.id,\n handler: handler_fn,\n handler_name,\n handler_file_path: record.handler_file_path ?? null,\n handler_timeout: record.handler_timeout,\n handler_slow_timeout: record.handler_slow_timeout,\n handler_registered_at: record.handler_registered_at,\n event_pattern: record.event_pattern,\n eventbus_name: record.eventbus_name,\n eventbus_id: record.eventbus_id,\n })\n }\n\n static toJSONArray(handlers: Iterable<EventHandler>): EventHandlerJSON[] {\n return Array.from(handlers, (handler) => handler.toJSON())\n }\n\n static fromJSONArray(data: unknown, handler?: EventHandlerCallable): EventHandler[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.map((item) => EventHandler.fromJSON(item, handler))\n }\n\n get eventbus_label(): string {\n return `${this.eventbus_name}#${this.eventbus_id.slice(-4)}`\n }\n}\n\n// Generic base TimeoutError used for EventHandlerTimeoutError.cause default value if\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'TimeoutError'\n }\n}\n\n// Base class for all errors that can occur while running an event handler\nexport class EventHandlerError extends Error {\n event_result: EventResult\n timeout_seconds: number | null\n cause: Error\n\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message)\n this.name = 'EventHandlerError'\n this.event_result = params.event_result\n this.cause = params.cause\n this.timeout_seconds = params.timeout_seconds ?? this.event_result.event.event_timeout ?? null\n }\n\n get event(): BaseEvent {\n return this.event_result.event\n }\n\n get event_type(): string {\n return this.event.event_type\n }\n\n get handler_name(): string {\n return this.event_result.handler_name\n }\n\n get handler_id(): string {\n return this.event_result.handler_id\n }\n\n get event_timeout(): number | null {\n return this.event.event_timeout\n }\n}\n\n// When the handler itself timed out while executing (due to handler.handler_timeout being exceeded)\nexport class EventHandlerTimeoutError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause?: Error }) {\n super(message, {\n event_result: params.event_result,\n timeout_seconds: params.timeout_seconds,\n cause: params.cause ?? new TimeoutError(message),\n })\n this.name = 'EventHandlerTimeoutError'\n }\n}\n\n// When a pending handler was cancelled and never run due to an error (e.g. timeout) in a parent scope\nexport class EventHandlerCancelledError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message, params)\n this.name = 'EventHandlerCancelledError'\n }\n}\n\n// When a handler that was already running was aborted due to an error in the parent scope, not due to an error in its own logic / exceeding its own timeout\nexport class EventHandlerAbortedError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message, params)\n this.name = 'EventHandlerAbortedError'\n }\n}\n\n// When a handler run successfully but returned a value that failed event_result_type validation\nexport class EventHandlerResultSchemaError extends EventHandlerError {\n raw_value: unknown\n\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error; raw_value: unknown }) {\n super(message, params)\n this.name = 'EventHandlerResultSchemaError'\n this.raw_value = params.raw_value\n }\n\n get expected_schema(): any {\n return this.event_result.event.event_result_type\n }\n}\n"],
4
+ "sourcesContent": ["import { z } from 'zod'\nimport { v5 as uuidv5 } from 'uuid'\n\nimport { normalizeEventPattern, type EventHandlerCallable, type EventPattern } from './types.js'\nimport { BaseEvent } from './BaseEvent.js'\nimport type { EventResult } from './EventResult.js'\nimport { monotonicDatetime } from './helpers.js'\n\nconst HANDLER_ID_NAMESPACE = uuidv5('abxbus-handler', uuidv5.DNS)\nconst BOUND_FUNCTION_PREFIX = 'bound '\n\nconst normalizeCallableName = (name: string | undefined): string => {\n if (!name) {\n return 'anonymous'\n }\n if (name.startsWith(BOUND_FUNCTION_PREFIX) && name.length > BOUND_FUNCTION_PREFIX.length) {\n return name.slice(BOUND_FUNCTION_PREFIX.length)\n }\n return name\n}\n\nexport type EphemeralFindEventHandler = {\n // Similar to a handler, except it's for .find() calls.\n // Resolved on dispatch, ephemeral, and never shows up in the processing tree.\n event_pattern: string | '*'\n matches: (event: BaseEvent) => boolean\n resolve: (event: BaseEvent | null) => void\n timeout_id?: ReturnType<typeof setTimeout>\n}\n\nexport const FindWaiterJSONSchema = z\n .object({\n event_pattern: z.union([z.string(), z.literal('*')]),\n has_timeout: z.boolean(),\n })\n .strict()\n\nexport type FindWaiterJSON = z.infer<typeof FindWaiterJSONSchema>\n\nexport class FindWaiter {\n static toJSON(waiter: EphemeralFindEventHandler): FindWaiterJSON {\n return {\n event_pattern: waiter.event_pattern,\n has_timeout: waiter.timeout_id !== undefined,\n }\n }\n\n static fromJSON(\n data: unknown,\n overrides: {\n matches?: (event: BaseEvent) => boolean\n resolve?: (event: BaseEvent | null) => void\n } = {}\n ): EphemeralFindEventHandler {\n const record = FindWaiterJSONSchema.parse(data)\n const event_pattern = record.event_pattern\n const defaultMatches = (event: BaseEvent): boolean => event_pattern === '*' || event.event_type === event_pattern\n return {\n event_pattern,\n matches: overrides.matches ?? defaultMatches,\n resolve: overrides.resolve ?? (() => {}),\n }\n }\n\n static toJSONArray(waiters: Iterable<EphemeralFindEventHandler>): FindWaiterJSON[] {\n return Array.from(waiters, (waiter) => FindWaiter.toJSON(waiter))\n }\n\n static fromJSONArray(\n data: unknown,\n overrides: {\n matches?: (event: BaseEvent) => boolean\n resolve?: (event: BaseEvent | null) => void\n } = {}\n ): EphemeralFindEventHandler[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.map((item) => FindWaiter.fromJSON(item, overrides))\n }\n}\n\nexport const EventHandlerJSONSchema = z\n .object({\n id: z.string(),\n eventbus_name: z.string(),\n eventbus_id: z.string().uuid(),\n event_pattern: z.union([z.string(), z.literal('*')]),\n handler_name: z.string(),\n handler_file_path: z.string().nullable().optional(),\n handler_timeout: z.number().nullable().optional(),\n handler_slow_timeout: z.number().nullable().optional(),\n handler_registered_at: z.string().datetime(),\n })\n .strict()\n\nexport type EventHandlerJSON = z.infer<typeof EventHandlerJSONSchema>\n\n// an entry in the list of event handlers that are registered on a bus\nexport class EventHandler {\n id: string // unique uuidv5 based on hash of bus name, handler name, handler file path:lineno, registered at timestamp, and event key\n handler: EventHandlerCallable // original callable passed to on()\n handler_name: string // name of the handler function, or 'anonymous' if the handler is an anonymous/arrow function\n handler_file_path: string | null // ~/path/to/source/file.ts:123, or null when unknown\n handler_timeout?: number | null // maximum time in seconds that the handler is allowed to run before it is aborted, resolved at runtime if not set\n handler_slow_timeout?: number | null // warning threshold in seconds for slow handler execution\n handler_registered_at: string // ISO datetime used in the deterministic handler-id seed\n event_pattern: string | '*' // event_type string to match against, or '*' to match all events\n eventbus_name: string // name of the event bus that the handler is registered on\n eventbus_id: string // uuidv7 identifier of the event bus that the handler is registered on\n\n constructor(params: {\n id?: string\n handler: EventHandlerCallable\n handler_name: string\n handler_file_path?: string | null\n handler_timeout?: number | null\n handler_slow_timeout?: number | null\n handler_registered_at: string\n event_pattern: string | '*'\n eventbus_name: string\n eventbus_id: string\n }) {\n const handler_registered_at = monotonicDatetime(params.handler_registered_at)\n this.id =\n params.id ??\n EventHandler.computeHandlerId({\n eventbus_id: params.eventbus_id,\n handler_name: params.handler_name,\n handler_file_path: params.handler_file_path,\n handler_registered_at,\n event_pattern: params.event_pattern,\n })\n this.handler = params.handler\n this.handler_name = params.handler_name\n this.handler_file_path = params.handler_file_path ?? null\n this.handler_timeout = params.handler_timeout\n this.handler_slow_timeout = params.handler_slow_timeout\n this.handler_registered_at = handler_registered_at\n this.event_pattern = params.event_pattern\n this.eventbus_name = params.eventbus_name\n this.eventbus_id = params.eventbus_id\n }\n\n get _handler_async(): EventHandlerCallable {\n const handler = this.handler\n if (Object.prototype.toString.call(handler) === '[object AsyncFunction]') {\n return handler\n }\n return async (event: BaseEvent) => await handler(event)\n }\n\n static handlerNameFromCallable(handler: EventHandlerCallable): string {\n return normalizeCallableName(handler.name)\n }\n\n // compute globally unique handler uuid as a hash of the bus name, handler name, handler file path, registered at timestamp, and event key\n static computeHandlerId(params: {\n eventbus_id: string\n handler_name: string\n handler_file_path?: string | null\n handler_registered_at: string\n event_pattern: string | '*'\n }): string {\n const file_path = params.handler_file_path ?? 'unknown'\n const seed = `${params.eventbus_id}|${params.handler_name}|${file_path}|${params.handler_registered_at}|${params.event_pattern}`\n return uuidv5(seed, HANDLER_ID_NAMESPACE)\n }\n\n static fromCallable<TEvent extends BaseEvent = BaseEvent>(params: {\n handler: EventHandlerCallable<TEvent>\n event_pattern: EventPattern | '*'\n eventbus_name: string\n eventbus_id: string\n detect_handler_file_path?: boolean\n id?: string\n handler_file_path?: string | null\n handler_timeout?: number | null\n handler_slow_timeout?: number | null\n handler_registered_at?: string\n }): EventHandler {\n const entry = new EventHandler({\n id: params.id,\n handler: params.handler as EventHandlerCallable,\n handler_name: EventHandler.handlerNameFromCallable(params.handler as EventHandlerCallable),\n handler_file_path: params.handler_file_path ?? null,\n handler_timeout: params.handler_timeout,\n handler_slow_timeout: params.handler_slow_timeout,\n handler_registered_at: monotonicDatetime(params.handler_registered_at),\n event_pattern: normalizeEventPattern(params.event_pattern),\n eventbus_name: params.eventbus_name,\n eventbus_id: params.eventbus_id,\n })\n const should_detect_handler_file_path = params.detect_handler_file_path ?? true\n if (should_detect_handler_file_path && entry.handler_file_path === null) {\n entry._detectHandlerFilePath()\n if (params.id === undefined) {\n entry.id = EventHandler.computeHandlerId({\n eventbus_id: entry.eventbus_id,\n handler_name: entry.handler_name,\n handler_file_path: entry.handler_file_path,\n handler_registered_at: entry.handler_registered_at,\n event_pattern: entry.event_pattern,\n })\n }\n }\n return entry\n }\n\n // \"someHandlerName() @ ~/path/to/source/file.ts:123\" <- best case when file path is available and its a named function\n // \"function#1234()\" <- worst case when no file path is available and its an anonymous/arrow function defined inline\n toString(): string {\n const label = this.handler_name && this.handler_name !== 'anonymous' ? `${this.handler_name}()` : `function#${this.id.slice(-4)}()`\n return this.handler_file_path ? `${label} @ ${this.handler_file_path}` : label\n }\n\n // autodetect the path/to/source/file.ts:lineno where the handler is defined for better logs\n // optional (controlled by EventBus.event_handler_detect_file_paths) because it can slow down performance to introspect stack traces and find file paths\n _detectHandlerFilePath(): void {\n const line = new Error().stack\n ?.split('\\n')\n .map((l) => l.trim())\n .filter(Boolean)[4]\n if (!line) return\n const resolved_path =\n line.trim().match(/\\(([^)]+)\\)$/)?.[1] ??\n line.trim().match(/^\\s*at\\s+(.+)$/)?.[1] ??\n line.trim().match(/^[^@]+@(.+)$/)?.[1] ??\n line.trim()\n const match = resolved_path.match(/^(.*?):(\\d+)(?::\\d+)?$/)\n let normalized = match ? match[1] : resolved_path\n const line_number = match?.[2]\n if (normalized.startsWith('file://')) {\n let path = normalized.slice('file://'.length)\n if (path.startsWith('localhost/')) path = path.slice('localhost'.length)\n if (!path.startsWith('/')) path = `/${path}`\n try {\n normalized = decodeURIComponent(path)\n } catch {\n normalized = path\n }\n }\n normalized = normalized.replace(/\\/users\\/[^/]+\\//i, '~/').replace(/\\/home\\/[^/]+\\//i, '~/')\n this.handler_file_path = line_number ? `${normalized}:${line_number}` : normalized\n }\n\n toJSON(): EventHandlerJSON {\n return {\n id: this.id,\n eventbus_name: this.eventbus_name,\n eventbus_id: this.eventbus_id,\n event_pattern: this.event_pattern,\n handler_name: this.handler_name,\n handler_file_path: this.handler_file_path,\n handler_timeout: this.handler_timeout,\n handler_slow_timeout: this.handler_slow_timeout,\n handler_registered_at: this.handler_registered_at,\n }\n }\n\n static fromJSON(data: unknown, handler?: EventHandlerCallable): EventHandler {\n const record = EventHandlerJSONSchema.parse(data)\n const handler_fn = handler ?? ((() => undefined) as EventHandlerCallable)\n const handler_name = record.handler_name || handler_fn.name || 'anonymous' // 'anonymous' is the default name for anonymous/arrow functions\n return new EventHandler({\n id: record.id,\n handler: handler_fn,\n handler_name,\n handler_file_path: record.handler_file_path ?? null,\n handler_timeout: record.handler_timeout,\n handler_slow_timeout: record.handler_slow_timeout,\n handler_registered_at: record.handler_registered_at,\n event_pattern: record.event_pattern,\n eventbus_name: record.eventbus_name,\n eventbus_id: record.eventbus_id,\n })\n }\n\n static toJSONArray(handlers: Iterable<EventHandler>): EventHandlerJSON[] {\n return Array.from(handlers, (handler) => handler.toJSON())\n }\n\n static fromJSONArray(data: unknown, handler?: EventHandlerCallable): EventHandler[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.map((item) => EventHandler.fromJSON(item, handler))\n }\n\n get eventbus_label(): string {\n return `${this.eventbus_name}#${this.eventbus_id.slice(-4)}`\n }\n}\n\n// Generic base TimeoutError used for EventHandlerTimeoutError.cause default value if\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'TimeoutError'\n }\n}\n\n// Base class for all errors that can occur while running an event handler\nexport class EventHandlerError extends Error {\n event_result: EventResult\n timeout_seconds: number | null\n cause: Error\n\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message)\n this.name = 'EventHandlerError'\n this.event_result = params.event_result\n this.cause = params.cause\n this.timeout_seconds = params.timeout_seconds ?? this.event_result.event.event_timeout ?? null\n }\n\n get event(): BaseEvent {\n return this.event_result.event\n }\n\n get event_type(): string {\n return this.event.event_type\n }\n\n get handler_name(): string {\n return this.event_result.handler_name\n }\n\n get handler_id(): string {\n return this.event_result.handler_id\n }\n\n get event_timeout(): number | null {\n return this.event.event_timeout\n }\n}\n\n// When the handler itself timed out while executing (due to handler.handler_timeout being exceeded)\nexport class EventHandlerTimeoutError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause?: Error }) {\n super(message, {\n event_result: params.event_result,\n timeout_seconds: params.timeout_seconds,\n cause: params.cause ?? new TimeoutError(message),\n })\n this.name = 'EventHandlerTimeoutError'\n }\n}\n\n// When a pending handler was cancelled and never run due to an error (e.g. timeout) in a parent scope\nexport class EventHandlerCancelledError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message, params)\n this.name = 'EventHandlerCancelledError'\n }\n}\n\n// When a handler that was already running was aborted due to an error in the parent scope, not due to an error in its own logic / exceeding its own timeout\nexport class EventHandlerAbortedError extends EventHandlerError {\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error }) {\n super(message, params)\n this.name = 'EventHandlerAbortedError'\n }\n}\n\n// When a handler run successfully but returned a value that failed event_result_type validation\nexport class EventHandlerResultSchemaError extends EventHandlerError {\n raw_value: unknown\n\n constructor(message: string, params: { event_result: EventResult; timeout_seconds?: number | null; cause: Error; raw_value: unknown }) {\n super(message, params)\n this.name = 'EventHandlerResultSchemaError'\n this.raw_value = params.raw_value\n }\n\n get expected_schema(): any {\n return this.event_result.event.event_result_type\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["uuidv5"]
7
7
  }
@@ -39,8 +39,8 @@ const EventResultJSONSchema = import_zod.z.object({
39
39
  handler_id: import_zod.z.string(),
40
40
  handler_name: import_zod.z.string(),
41
41
  handler_file_path: import_zod.z.string().nullable().optional(),
42
- handler_timeout: import_zod.z.number().nullable().optional(),
43
- handler_slow_timeout: import_zod.z.number().nullable().optional(),
42
+ handler_timeout: import_zod.z.number().nonnegative().nullable().optional(),
43
+ handler_slow_timeout: import_zod.z.number().nonnegative().nullable().optional(),
44
44
  handler_registered_at: import_zod.z.string().datetime().optional(),
45
45
  handler_event_pattern: import_zod.z.union([import_zod.z.string(), import_zod.z.literal("*")]).optional(),
46
46
  eventbus_name: import_zod.z.string(),
@@ -169,17 +169,21 @@ class EventResult {
169
169
  }
170
170
  return this.result;
171
171
  }
172
- // Resolve handler timeout in seconds using precedence: handler -> event -> bus defaults.
172
+ // Resolve handler timeout in seconds using event-local values plus the executing bus defaults.
173
173
  get handler_timeout() {
174
174
  const original = this.event._event_original ?? this.event;
175
- const resolved_event_timeout = original.event_timeout ?? this.bus.event_timeout;
175
+ const raw_event_timeout = original.event_timeout ?? this.bus.event_timeout;
176
+ const resolved_event_timeout = raw_event_timeout !== null && raw_event_timeout !== void 0 && raw_event_timeout > 0 ? raw_event_timeout : null;
176
177
  let resolved_handler_timeout;
177
- if (this.handler.handler_timeout !== void 0) {
178
+ if (this.handler.handler_timeout !== void 0 && this.handler.handler_timeout !== null) {
178
179
  resolved_handler_timeout = this.handler.handler_timeout;
179
- } else if (original.event_handler_timeout !== void 0) {
180
+ } else if (original.event_handler_timeout !== void 0 && original.event_handler_timeout !== null) {
180
181
  resolved_handler_timeout = original.event_handler_timeout;
181
182
  } else {
182
- resolved_handler_timeout = this.bus.event_timeout;
183
+ resolved_handler_timeout = resolved_event_timeout;
184
+ }
185
+ if (resolved_handler_timeout !== null && resolved_handler_timeout <= 0) {
186
+ resolved_handler_timeout = null;
183
187
  }
184
188
  if (resolved_handler_timeout === null && resolved_event_timeout === null) {
185
189
  return null;
@@ -192,29 +196,19 @@ class EventResult {
192
196
  }
193
197
  return Math.min(resolved_handler_timeout, resolved_event_timeout);
194
198
  }
195
- // Resolve slow handler warning threshold in seconds using precedence: handler -> event -> bus defaults.
199
+ // Resolve slow handler warning threshold in seconds using event-local values plus the executing bus defaults.
196
200
  get handler_slow_timeout() {
197
201
  const original = this.event._event_original ?? this.event;
198
- if (this.handler.handler_slow_timeout !== void 0) {
202
+ if (this.handler.handler_slow_timeout !== void 0 && this.handler.handler_slow_timeout !== null) {
199
203
  return this.handler.handler_slow_timeout;
200
204
  }
201
- if (original.event_handler_slow_timeout !== void 0) {
202
- return original.event_handler_slow_timeout;
203
- }
204
- const event_slow_timeout = original.event_slow_timeout;
205
- if (event_slow_timeout !== void 0) {
206
- return event_slow_timeout;
207
- }
208
- if (this.bus?.event_handler_slow_timeout !== void 0) {
209
- return this.bus.event_handler_slow_timeout;
210
- }
211
- return this.bus?.event_slow_timeout ?? null;
205
+ return original.event_handler_slow_timeout ?? this.bus.event_handler_slow_timeout ?? null;
212
206
  }
213
207
  // Create a slow-handler warning timer that logs if the handler runs too long.
214
208
  _createSlowHandlerWarningTimer(effective_timeout) {
215
209
  const handler_warn_timeout = this.handler_slow_timeout;
216
- const warn_ms = handler_warn_timeout === null ? null : handler_warn_timeout * 1e3;
217
- const should_warn = warn_ms !== null && (effective_timeout === null || effective_timeout * 1e3 > warn_ms);
210
+ const warn_ms = handler_warn_timeout === null || handler_warn_timeout <= 0 ? null : handler_warn_timeout * 1e3;
211
+ const should_warn = warn_ms !== null && (effective_timeout === null || effective_timeout <= 0 || effective_timeout * 1e3 > warn_ms);
218
212
  if (!should_warn || warn_ms === null) {
219
213
  return null;
220
214
  }