abxbus 2.4.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 (137) hide show
  1. package/README.md +647 -0
  2. package/dist/cjs/async_context.d.ts +12 -0
  3. package/dist/cjs/async_context.js +70 -0
  4. package/dist/cjs/async_context.js.map +7 -0
  5. package/dist/cjs/base_event.d.ts +207 -0
  6. package/dist/cjs/base_event.js +871 -0
  7. package/dist/cjs/base_event.js.map +7 -0
  8. package/dist/cjs/bridge_jsonl.d.ts +26 -0
  9. package/dist/cjs/bridge_jsonl.js +170 -0
  10. package/dist/cjs/bridge_jsonl.js.map +7 -0
  11. package/dist/cjs/bridge_nats.d.ts +20 -0
  12. package/dist/cjs/bridge_nats.js +108 -0
  13. package/dist/cjs/bridge_nats.js.map +7 -0
  14. package/dist/cjs/bridge_postgres.d.ts +31 -0
  15. package/dist/cjs/bridge_postgres.js +251 -0
  16. package/dist/cjs/bridge_postgres.js.map +7 -0
  17. package/dist/cjs/bridge_redis.d.ts +34 -0
  18. package/dist/cjs/bridge_redis.js +175 -0
  19. package/dist/cjs/bridge_redis.js.map +7 -0
  20. package/dist/cjs/bridge_sqlite.d.ts +30 -0
  21. package/dist/cjs/bridge_sqlite.js +255 -0
  22. package/dist/cjs/bridge_sqlite.js.map +7 -0
  23. package/dist/cjs/bridges.d.ts +49 -0
  24. package/dist/cjs/bridges.js +326 -0
  25. package/dist/cjs/bridges.js.map +7 -0
  26. package/dist/cjs/event_bus.d.ts +127 -0
  27. package/dist/cjs/event_bus.js +1058 -0
  28. package/dist/cjs/event_bus.js.map +7 -0
  29. package/dist/cjs/event_handler.d.ts +139 -0
  30. package/dist/cjs/event_handler.js +299 -0
  31. package/dist/cjs/event_handler.js.map +7 -0
  32. package/dist/cjs/event_history.d.ts +45 -0
  33. package/dist/cjs/event_history.js +192 -0
  34. package/dist/cjs/event_history.js.map +7 -0
  35. package/dist/cjs/event_result.d.ts +86 -0
  36. package/dist/cjs/event_result.js +446 -0
  37. package/dist/cjs/event_result.js.map +7 -0
  38. package/dist/cjs/events_suck.d.ts +40 -0
  39. package/dist/cjs/events_suck.js +59 -0
  40. package/dist/cjs/events_suck.js.map +7 -0
  41. package/dist/cjs/helpers.d.ts +1 -0
  42. package/dist/cjs/helpers.js +84 -0
  43. package/dist/cjs/helpers.js.map +7 -0
  44. package/dist/cjs/index.d.ts +17 -0
  45. package/dist/cjs/index.js +54 -0
  46. package/dist/cjs/index.js.map +7 -0
  47. package/dist/cjs/lock_manager.d.ts +70 -0
  48. package/dist/cjs/lock_manager.js +343 -0
  49. package/dist/cjs/lock_manager.js.map +7 -0
  50. package/dist/cjs/logging.d.ts +16 -0
  51. package/dist/cjs/logging.js +216 -0
  52. package/dist/cjs/logging.js.map +7 -0
  53. package/dist/cjs/middlewares.d.ts +13 -0
  54. package/dist/cjs/middlewares.js +17 -0
  55. package/dist/cjs/middlewares.js.map +7 -0
  56. package/dist/cjs/optional_deps.d.ts +3 -0
  57. package/dist/cjs/optional_deps.js +64 -0
  58. package/dist/cjs/optional_deps.js.map +7 -0
  59. package/dist/cjs/package.json +5 -0
  60. package/dist/cjs/retry.d.ts +52 -0
  61. package/dist/cjs/retry.js +257 -0
  62. package/dist/cjs/retry.js.map +7 -0
  63. package/dist/cjs/timing.d.ts +3 -0
  64. package/dist/cjs/timing.js +76 -0
  65. package/dist/cjs/timing.js.map +7 -0
  66. package/dist/cjs/type_inference.test.d.ts +1 -0
  67. package/dist/cjs/types.d.ts +36 -0
  68. package/dist/cjs/types.js +104 -0
  69. package/dist/cjs/types.js.map +7 -0
  70. package/dist/esm/async_context.js +50 -0
  71. package/dist/esm/async_context.js.map +7 -0
  72. package/dist/esm/base_event.js +857 -0
  73. package/dist/esm/base_event.js.map +7 -0
  74. package/dist/esm/bridge_jsonl.js +150 -0
  75. package/dist/esm/bridge_jsonl.js.map +7 -0
  76. package/dist/esm/bridge_nats.js +88 -0
  77. package/dist/esm/bridge_nats.js.map +7 -0
  78. package/dist/esm/bridge_postgres.js +231 -0
  79. package/dist/esm/bridge_postgres.js.map +7 -0
  80. package/dist/esm/bridge_redis.js +155 -0
  81. package/dist/esm/bridge_redis.js.map +7 -0
  82. package/dist/esm/bridge_sqlite.js +235 -0
  83. package/dist/esm/bridge_sqlite.js.map +7 -0
  84. package/dist/esm/bridges.js +306 -0
  85. package/dist/esm/bridges.js.map +7 -0
  86. package/dist/esm/event_bus.js +1046 -0
  87. package/dist/esm/event_bus.js.map +7 -0
  88. package/dist/esm/event_handler.js +279 -0
  89. package/dist/esm/event_handler.js.map +7 -0
  90. package/dist/esm/event_history.js +172 -0
  91. package/dist/esm/event_history.js.map +7 -0
  92. package/dist/esm/event_result.js +426 -0
  93. package/dist/esm/event_result.js.map +7 -0
  94. package/dist/esm/events_suck.js +39 -0
  95. package/dist/esm/events_suck.js.map +7 -0
  96. package/dist/esm/helpers.js +64 -0
  97. package/dist/esm/helpers.js.map +7 -0
  98. package/dist/esm/index.js +47 -0
  99. package/dist/esm/index.js.map +7 -0
  100. package/dist/esm/lock_manager.js +323 -0
  101. package/dist/esm/lock_manager.js.map +7 -0
  102. package/dist/esm/logging.js +196 -0
  103. package/dist/esm/logging.js.map +7 -0
  104. package/dist/esm/middlewares.js +1 -0
  105. package/dist/esm/middlewares.js.map +7 -0
  106. package/dist/esm/optional_deps.js +44 -0
  107. package/dist/esm/optional_deps.js.map +7 -0
  108. package/dist/esm/retry.js +237 -0
  109. package/dist/esm/retry.js.map +7 -0
  110. package/dist/esm/timing.js +56 -0
  111. package/dist/esm/timing.js.map +7 -0
  112. package/dist/esm/types.js +84 -0
  113. package/dist/esm/types.js.map +7 -0
  114. package/dist/types/async_context.d.ts +12 -0
  115. package/dist/types/base_event.d.ts +207 -0
  116. package/dist/types/bridge_jsonl.d.ts +26 -0
  117. package/dist/types/bridge_nats.d.ts +20 -0
  118. package/dist/types/bridge_postgres.d.ts +31 -0
  119. package/dist/types/bridge_redis.d.ts +34 -0
  120. package/dist/types/bridge_sqlite.d.ts +30 -0
  121. package/dist/types/bridges.d.ts +49 -0
  122. package/dist/types/event_bus.d.ts +127 -0
  123. package/dist/types/event_handler.d.ts +139 -0
  124. package/dist/types/event_history.d.ts +45 -0
  125. package/dist/types/event_result.d.ts +86 -0
  126. package/dist/types/events_suck.d.ts +40 -0
  127. package/dist/types/helpers.d.ts +1 -0
  128. package/dist/types/index.d.ts +17 -0
  129. package/dist/types/lock_manager.d.ts +70 -0
  130. package/dist/types/logging.d.ts +16 -0
  131. package/dist/types/middlewares.d.ts +13 -0
  132. package/dist/types/optional_deps.d.ts +3 -0
  133. package/dist/types/retry.d.ts +52 -0
  134. package/dist/types/timing.d.ts +3 -0
  135. package/dist/types/type_inference.test.d.ts +1 -0
  136. package/dist/types/types.d.ts +36 -0
  137. package/package.json +87 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/event_handler.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 './base_event.js'\nimport type { EventResult } from './event_result.js'\nimport { monotonicDatetime } from './helpers.js'\n\nconst HANDLER_ID_NAMESPACE = uuidv5('abxbus-handler', uuidv5.DNS)\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 // 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: params.handler.name || 'anonymous',\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
+ "mappings": "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",
6
+ "names": ["uuidv5"]
7
+ }
@@ -0,0 +1,45 @@
1
+ import { BaseEvent } from './base_event.js';
2
+ import type { EventPattern, FindWindow } from './types.js';
3
+ export type EventHistoryFindOptions = {
4
+ past?: FindWindow;
5
+ future?: FindWindow;
6
+ child_of?: BaseEvent | null;
7
+ event_is_child_of?: (event: BaseEvent, ancestor: BaseEvent) => boolean;
8
+ wait_for_future_match?: (event_pattern: string | '*', matches: (event: BaseEvent) => boolean, future: FindWindow) => Promise<BaseEvent | null>;
9
+ } & Record<string, unknown>;
10
+ export type EventHistoryTrimOptions<TEvent extends BaseEvent = BaseEvent> = {
11
+ is_event_complete?: (event: TEvent) => boolean;
12
+ on_remove?: (event: TEvent) => void;
13
+ owner_label?: string;
14
+ max_history_size?: number | null;
15
+ max_history_drop?: boolean;
16
+ };
17
+ export declare class EventHistory<TEvent extends BaseEvent = BaseEvent> implements Iterable<[string, TEvent]> {
18
+ max_history_size: number | null;
19
+ max_history_drop: boolean;
20
+ private _events;
21
+ private _warned_about_dropping_uncompleted_events;
22
+ constructor(options?: {
23
+ max_history_size?: number | null;
24
+ max_history_drop?: boolean;
25
+ });
26
+ get size(): number;
27
+ [Symbol.iterator](): Iterator<[string, TEvent]>;
28
+ entries(): IterableIterator<[string, TEvent]>;
29
+ keys(): IterableIterator<string>;
30
+ values(): IterableIterator<TEvent>;
31
+ clear(): void;
32
+ get(event_id: string): TEvent | undefined;
33
+ set(event_id: string, event: TEvent): this;
34
+ has(event_id: string): boolean;
35
+ delete(event_id: string): boolean;
36
+ addEvent(event: TEvent): void;
37
+ getEvent(event_id: string): TEvent | undefined;
38
+ removeEvent(event_id: string): boolean;
39
+ hasEvent(event_id: string): boolean;
40
+ static normalizeEventPattern(event_pattern: EventPattern | '*'): string | '*';
41
+ find(event_pattern: '*', where?: (event: TEvent) => boolean, options?: EventHistoryFindOptions): Promise<TEvent | null>;
42
+ find<TMatch extends TEvent>(event_pattern: EventPattern<TMatch>, where?: (event: TMatch) => boolean, options?: EventHistoryFindOptions): Promise<TMatch | null>;
43
+ trimEventHistory(options?: EventHistoryTrimOptions<TEvent>): number;
44
+ private eventIsChildOf;
45
+ }
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var event_history_exports = {};
20
+ __export(event_history_exports, {
21
+ EventHistory: () => EventHistory
22
+ });
23
+ module.exports = __toCommonJS(event_history_exports);
24
+ var import_types = require("./types.js");
25
+ var import_helpers = require("./helpers.js");
26
+ class EventHistory {
27
+ max_history_size;
28
+ max_history_drop;
29
+ _events;
30
+ _warned_about_dropping_uncompleted_events;
31
+ constructor(options = {}) {
32
+ this.max_history_size = options.max_history_size === void 0 ? 100 : options.max_history_size;
33
+ this.max_history_drop = options.max_history_drop ?? false;
34
+ this._events = /* @__PURE__ */ new Map();
35
+ this._warned_about_dropping_uncompleted_events = false;
36
+ }
37
+ get size() {
38
+ return this._events.size;
39
+ }
40
+ [Symbol.iterator]() {
41
+ return this._events[Symbol.iterator]();
42
+ }
43
+ entries() {
44
+ return this._events.entries();
45
+ }
46
+ keys() {
47
+ return this._events.keys();
48
+ }
49
+ values() {
50
+ return this._events.values();
51
+ }
52
+ clear() {
53
+ this._events.clear();
54
+ }
55
+ get(event_id) {
56
+ return this._events.get(event_id);
57
+ }
58
+ set(event_id, event) {
59
+ this._events.set(event_id, event);
60
+ return this;
61
+ }
62
+ has(event_id) {
63
+ return this._events.has(event_id);
64
+ }
65
+ delete(event_id) {
66
+ return this._events.delete(event_id);
67
+ }
68
+ addEvent(event) {
69
+ this._events.set(event.event_id, event);
70
+ }
71
+ getEvent(event_id) {
72
+ return this._events.get(event_id);
73
+ }
74
+ removeEvent(event_id) {
75
+ return this._events.delete(event_id);
76
+ }
77
+ hasEvent(event_id) {
78
+ return this._events.has(event_id);
79
+ }
80
+ static normalizeEventPattern(event_pattern) {
81
+ return (0, import_types.normalizeEventPattern)(event_pattern);
82
+ }
83
+ async find(event_pattern, where = () => true, options = {}) {
84
+ const past = options.past ?? true;
85
+ const future = options.future ?? false;
86
+ const child_of = options.child_of ?? null;
87
+ const eventIsChildOf = options.event_is_child_of ?? ((event, ancestor) => this.eventIsChildOf(event, ancestor));
88
+ const waitForFutureMatch = options.wait_for_future_match;
89
+ if (past === false && future === false) {
90
+ return null;
91
+ }
92
+ const event_key = EventHistory.normalizeEventPattern(event_pattern);
93
+ const cutoff_at = past === true ? null : (0, import_helpers.monotonicDatetime)(new Date(Date.now() - Math.max(0, Number(past)) * 1e3).toISOString());
94
+ const event_field_filters = Object.entries(options).filter(
95
+ ([key, value]) => key !== "past" && key !== "future" && key !== "child_of" && key !== "event_is_child_of" && key !== "wait_for_future_match" && value !== void 0
96
+ );
97
+ const matches = (event) => (event_key === "*" || event.event_type === event_key) && (!child_of || eventIsChildOf(event, child_of)) && event_field_filters.every(([field_name, expected]) => event[field_name] === expected) && where(event);
98
+ if (past !== false) {
99
+ const history_values = Array.from(this._events.values());
100
+ for (let i = history_values.length - 1; i >= 0; i -= 1) {
101
+ const event = history_values[i];
102
+ if (cutoff_at !== null && event.event_created_at < cutoff_at) {
103
+ continue;
104
+ }
105
+ if (matches(event)) {
106
+ return event;
107
+ }
108
+ }
109
+ }
110
+ if (future === false || !waitForFutureMatch) {
111
+ return null;
112
+ }
113
+ return await waitForFutureMatch(event_key, matches, future);
114
+ }
115
+ trimEventHistory(options = {}) {
116
+ const max_history_size = options.max_history_size ?? this.max_history_size;
117
+ const max_history_drop = options.max_history_drop ?? this.max_history_drop;
118
+ if (max_history_size === null) {
119
+ return 0;
120
+ }
121
+ const is_event_complete = options.is_event_complete ?? ((event) => event.event_status === "completed");
122
+ const on_remove = options.on_remove;
123
+ if (max_history_size === 0) {
124
+ let removed_count2 = 0;
125
+ for (const [event_id, event] of Array.from(this._events.entries())) {
126
+ if (!is_event_complete(event)) {
127
+ continue;
128
+ }
129
+ this._events.delete(event_id);
130
+ on_remove?.(event);
131
+ removed_count2 += 1;
132
+ }
133
+ return removed_count2;
134
+ }
135
+ if (!max_history_drop || this.size <= max_history_size) {
136
+ return 0;
137
+ }
138
+ let remaining_overage = this.size - max_history_size;
139
+ let removed_count = 0;
140
+ const remove_event = (event_id, event) => {
141
+ this._events.delete(event_id);
142
+ on_remove?.(event);
143
+ removed_count += 1;
144
+ };
145
+ for (const [event_id, event] of Array.from(this._events.entries())) {
146
+ if (remaining_overage <= 0) {
147
+ break;
148
+ }
149
+ if (!is_event_complete(event)) {
150
+ continue;
151
+ }
152
+ remove_event(event_id, event);
153
+ remaining_overage -= 1;
154
+ }
155
+ let dropped_uncompleted = 0;
156
+ for (const [event_id, event] of Array.from(this._events.entries())) {
157
+ if (remaining_overage <= 0) {
158
+ break;
159
+ }
160
+ if (!is_event_complete(event)) {
161
+ dropped_uncompleted += 1;
162
+ }
163
+ remove_event(event_id, event);
164
+ remaining_overage -= 1;
165
+ }
166
+ if (dropped_uncompleted > 0 && !this._warned_about_dropping_uncompleted_events) {
167
+ this._warned_about_dropping_uncompleted_events = true;
168
+ const owner_label = options.owner_label ?? "EventBus";
169
+ console.error(
170
+ `[abxbus] \u26A0\uFE0F Bus ${owner_label} has exceeded max_history_size=${max_history_size} and is dropping oldest history entries (even uncompleted events). Increase max_history_size or set max_history_drop=false to reject.`
171
+ );
172
+ }
173
+ return removed_count;
174
+ }
175
+ eventIsChildOf(event, ancestor) {
176
+ let current_parent_id = event.event_parent_id;
177
+ const visited = /* @__PURE__ */ new Set();
178
+ while (current_parent_id && !visited.has(current_parent_id)) {
179
+ if (current_parent_id === ancestor.event_id) {
180
+ return true;
181
+ }
182
+ visited.add(current_parent_id);
183
+ const parent = this._events.get(current_parent_id);
184
+ if (!parent) {
185
+ return false;
186
+ }
187
+ current_parent_id = parent.event_parent_id;
188
+ }
189
+ return false;
190
+ }
191
+ }
192
+ //# sourceMappingURL=event_history.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/event_history.ts"],
4
+ "sourcesContent": ["import { BaseEvent } from './base_event.js'\nimport type { EventPattern, FindWindow } from './types.js'\nimport { normalizeEventPattern } from './types.js'\nimport { monotonicDatetime } from './helpers.js'\n\nexport type EventHistoryFindOptions = {\n past?: FindWindow\n future?: FindWindow\n child_of?: BaseEvent | null\n event_is_child_of?: (event: BaseEvent, ancestor: BaseEvent) => boolean\n wait_for_future_match?: (\n event_pattern: string | '*',\n matches: (event: BaseEvent) => boolean,\n future: FindWindow\n ) => Promise<BaseEvent | null>\n} & Record<string, unknown>\n\nexport type EventHistoryTrimOptions<TEvent extends BaseEvent = BaseEvent> = {\n is_event_complete?: (event: TEvent) => boolean\n on_remove?: (event: TEvent) => void\n owner_label?: string\n max_history_size?: number | null\n max_history_drop?: boolean\n}\n\nexport class EventHistory<TEvent extends BaseEvent = BaseEvent> implements Iterable<[string, TEvent]> {\n max_history_size: number | null\n max_history_drop: boolean\n\n private _events: Map<string, TEvent>\n private _warned_about_dropping_uncompleted_events: boolean\n\n constructor(options: { max_history_size?: number | null; max_history_drop?: boolean } = {}) {\n this.max_history_size = options.max_history_size === undefined ? 100 : options.max_history_size\n this.max_history_drop = options.max_history_drop ?? false\n this._events = new Map()\n this._warned_about_dropping_uncompleted_events = false\n }\n\n get size(): number {\n return this._events.size\n }\n\n [Symbol.iterator](): Iterator<[string, TEvent]> {\n return this._events[Symbol.iterator]()\n }\n\n entries(): IterableIterator<[string, TEvent]> {\n return this._events.entries()\n }\n\n keys(): IterableIterator<string> {\n return this._events.keys()\n }\n\n values(): IterableIterator<TEvent> {\n return this._events.values()\n }\n\n clear(): void {\n this._events.clear()\n }\n\n get(event_id: string): TEvent | undefined {\n return this._events.get(event_id)\n }\n\n set(event_id: string, event: TEvent): this {\n this._events.set(event_id, event)\n return this\n }\n\n has(event_id: string): boolean {\n return this._events.has(event_id)\n }\n\n delete(event_id: string): boolean {\n return this._events.delete(event_id)\n }\n\n addEvent(event: TEvent): void {\n this._events.set(event.event_id, event)\n }\n\n getEvent(event_id: string): TEvent | undefined {\n return this._events.get(event_id)\n }\n\n removeEvent(event_id: string): boolean {\n return this._events.delete(event_id)\n }\n\n hasEvent(event_id: string): boolean {\n return this._events.has(event_id)\n }\n\n static normalizeEventPattern(event_pattern: EventPattern | '*'): string | '*' {\n return normalizeEventPattern(event_pattern)\n }\n\n find(event_pattern: '*', where?: (event: TEvent) => boolean, options?: EventHistoryFindOptions): Promise<TEvent | null>\n find<TMatch extends TEvent>(\n event_pattern: EventPattern<TMatch>,\n where?: (event: TMatch) => boolean,\n options?: EventHistoryFindOptions\n ): Promise<TMatch | null>\n async find(\n event_pattern: EventPattern<TEvent> | '*',\n where: (event: TEvent) => boolean = () => true,\n options: EventHistoryFindOptions = {}\n ): Promise<TEvent | null> {\n const past = options.past ?? true\n const future = options.future ?? false\n const child_of = options.child_of ?? null\n const eventIsChildOf = options.event_is_child_of ?? ((event: BaseEvent, ancestor: BaseEvent) => this.eventIsChildOf(event, ancestor))\n const waitForFutureMatch = options.wait_for_future_match\n if (past === false && future === false) {\n return null\n }\n\n const event_key = EventHistory.normalizeEventPattern(event_pattern)\n const cutoff_at = past === true ? null : monotonicDatetime(new Date(Date.now() - Math.max(0, Number(past)) * 1000).toISOString())\n\n const event_field_filters = Object.entries(options).filter(\n ([key, value]) =>\n key !== 'past' &&\n key !== 'future' &&\n key !== 'child_of' &&\n key !== 'event_is_child_of' &&\n key !== 'wait_for_future_match' &&\n value !== undefined\n )\n\n const matches = (event: BaseEvent): boolean =>\n (event_key === '*' || event.event_type === event_key) &&\n (!child_of || eventIsChildOf(event, child_of)) &&\n event_field_filters.every(([field_name, expected]) => (event as unknown as Record<string, unknown>)[field_name] === expected) &&\n where(event as TEvent)\n\n if (past !== false) {\n const history_values = Array.from(this._events.values())\n for (let i = history_values.length - 1; i >= 0; i -= 1) {\n const event = history_values[i]\n if (cutoff_at !== null && event.event_created_at < cutoff_at) {\n continue\n }\n if (matches(event)) {\n return event\n }\n }\n }\n\n if (future === false || !waitForFutureMatch) {\n return null\n }\n\n return (await waitForFutureMatch(event_key, matches, future)) as TEvent | null\n }\n\n trimEventHistory(options: EventHistoryTrimOptions<TEvent> = {}): number {\n const max_history_size = options.max_history_size ?? this.max_history_size\n const max_history_drop = options.max_history_drop ?? this.max_history_drop\n if (max_history_size === null) {\n return 0\n }\n\n const is_event_complete = options.is_event_complete ?? ((event: TEvent) => event.event_status === 'completed')\n const on_remove = options.on_remove\n\n if (max_history_size === 0) {\n let removed_count = 0\n for (const [event_id, event] of Array.from(this._events.entries())) {\n if (!is_event_complete(event)) {\n continue\n }\n this._events.delete(event_id)\n on_remove?.(event)\n removed_count += 1\n }\n return removed_count\n }\n\n if (!max_history_drop || this.size <= max_history_size) {\n return 0\n }\n\n let remaining_overage = this.size - max_history_size\n let removed_count = 0\n const remove_event = (event_id: string, event: TEvent): void => {\n this._events.delete(event_id)\n on_remove?.(event)\n removed_count += 1\n }\n\n for (const [event_id, event] of Array.from(this._events.entries())) {\n if (remaining_overage <= 0) {\n break\n }\n if (!is_event_complete(event)) {\n continue\n }\n remove_event(event_id, event)\n remaining_overage -= 1\n }\n\n let dropped_uncompleted = 0\n for (const [event_id, event] of Array.from(this._events.entries())) {\n if (remaining_overage <= 0) {\n break\n }\n if (!is_event_complete(event)) {\n dropped_uncompleted += 1\n }\n remove_event(event_id, event)\n remaining_overage -= 1\n }\n\n if (dropped_uncompleted > 0 && !this._warned_about_dropping_uncompleted_events) {\n this._warned_about_dropping_uncompleted_events = true\n const owner_label = options.owner_label ?? 'EventBus'\n console.error(\n `[abxbus] \u26A0\uFE0F Bus ${owner_label} has exceeded max_history_size=${max_history_size} and is dropping oldest history entries (even uncompleted events). Increase max_history_size or set max_history_drop=false to reject.`\n )\n }\n\n return removed_count\n }\n\n private eventIsChildOf(event: BaseEvent, ancestor: BaseEvent): boolean {\n let current_parent_id = event.event_parent_id\n const visited = new Set<string>()\n\n while (current_parent_id && !visited.has(current_parent_id)) {\n if (current_parent_id === ancestor.event_id) {\n return true\n }\n visited.add(current_parent_id)\n const parent = this._events.get(current_parent_id)\n if (!parent) {\n return false\n }\n current_parent_id = parent.event_parent_id\n }\n\n return false\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["removed_count"]
7
+ }
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod';
2
+ import { BaseEvent } from './base_event.js';
3
+ import type { EventBus } from './event_bus.js';
4
+ import { EventHandler } from './event_handler.js';
5
+ import { type HandlerLock } from './lock_manager.js';
6
+ import type { Deferred } from './lock_manager.js';
7
+ import type { EventResultType } from './types.js';
8
+ export type EventResultStatus = 'pending' | 'started' | 'completed' | 'error';
9
+ export declare const EventResultJSONSchema: z.ZodObject<{
10
+ id: z.ZodString;
11
+ status: z.ZodEnum<{
12
+ pending: "pending";
13
+ started: "started";
14
+ completed: "completed";
15
+ error: "error";
16
+ }>;
17
+ event_id: z.ZodString;
18
+ handler_id: z.ZodString;
19
+ handler_name: z.ZodString;
20
+ handler_file_path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ handler_timeout: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
22
+ handler_slow_timeout: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
23
+ handler_registered_at: z.ZodOptional<z.ZodString>;
24
+ handler_event_pattern: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"*">]>>;
25
+ eventbus_name: z.ZodString;
26
+ eventbus_id: z.ZodString;
27
+ started_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
28
+ completed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ result: z.ZodOptional<z.ZodUnknown>;
30
+ error: z.ZodOptional<z.ZodUnknown>;
31
+ event_children: z.ZodArray<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ export type EventResultJSON = z.infer<typeof EventResultJSONSchema>;
34
+ export declare class EventResult<TEvent extends BaseEvent = BaseEvent> {
35
+ id: string;
36
+ status: EventResultStatus;
37
+ event: TEvent;
38
+ handler: EventHandler;
39
+ started_at: string | null;
40
+ completed_at: string | null;
41
+ result?: EventResultType<TEvent>;
42
+ error?: unknown;
43
+ event_children: BaseEvent[];
44
+ _abort: Deferred<never> | null;
45
+ _lock: HandlerLock | null;
46
+ _queue_jump_pause_releases: Map<EventBus, () => void> | null;
47
+ constructor(params: {
48
+ event: TEvent;
49
+ handler: EventHandler;
50
+ });
51
+ toString(): string;
52
+ get event_id(): string;
53
+ get bus(): EventBus;
54
+ get handler_id(): string;
55
+ get handler_name(): string;
56
+ get handler_file_path(): string | null;
57
+ get eventbus_name(): string;
58
+ get eventbus_id(): string;
59
+ get eventbus_label(): string;
60
+ private getHookBus;
61
+ private _notifyStatusHook;
62
+ get value(): EventResultType<TEvent> | undefined;
63
+ get result_type(): TEvent['event_result_type'];
64
+ _linkEmittedChildEvent(child_event: BaseEvent): void;
65
+ get raw_value(): EventResultType<TEvent> | undefined;
66
+ get handler_timeout(): number | null;
67
+ get handler_slow_timeout(): number | null;
68
+ _createSlowHandlerWarningTimer(effective_timeout: number | null): ReturnType<typeof setTimeout> | null;
69
+ _ensureQueueJumpPause(bus: EventBus): void;
70
+ _releaseQueueJumpPauses(): void;
71
+ update(params: {
72
+ status?: EventResultStatus;
73
+ result?: EventResultType<TEvent> | BaseEvent | undefined;
74
+ error?: unknown;
75
+ }): this;
76
+ private _createHandlerTimeoutError;
77
+ private _handleHandlerError;
78
+ private _onHandlerExit;
79
+ runHandler(handler_lock: HandlerLock | null): Promise<void>;
80
+ _signalAbort(error: Error): void;
81
+ _markStarted(notify_hook?: boolean): Promise<never>;
82
+ _markCompleted(result: EventResultType<TEvent> | BaseEvent | undefined, notify_hook?: boolean): void;
83
+ _markError(error: unknown, notify_hook?: boolean): void;
84
+ toJSON(): EventResultJSON;
85
+ static fromJSON<TEvent extends BaseEvent>(event: TEvent, data: unknown): EventResult<TEvent>;
86
+ }