abxbus 2.4.24 → 2.4.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BaseEvent.d.ts +211 -0
- package/dist/cjs/{base_event.js → BaseEvent.js} +23 -23
- package/dist/cjs/BaseEvent.js.map +7 -0
- package/dist/cjs/EventBridge.d.ts +34 -0
- package/dist/cjs/EventBridge.js +295 -0
- package/dist/cjs/EventBridge.js.map +7 -0
- package/dist/cjs/EventBus.d.ts +125 -0
- package/dist/cjs/{event_bus.js → EventBus.js} +21 -21
- package/dist/cjs/EventBus.js.map +7 -0
- package/dist/cjs/EventBusMiddleware.d.ts +13 -0
- package/dist/cjs/EventBusMiddleware.js +17 -0
- package/dist/cjs/EventBusMiddleware.js.map +7 -0
- package/dist/cjs/EventHandler.d.ts +140 -0
- package/dist/cjs/{event_handler.js → EventHandler.js} +4 -4
- package/dist/cjs/EventHandler.js.map +7 -0
- package/dist/cjs/EventHistory.d.ts +45 -0
- package/dist/cjs/{event_history.js → EventHistory.js} +4 -4
- package/dist/cjs/EventHistory.js.map +7 -0
- package/dist/cjs/EventResult.d.ts +86 -0
- package/dist/cjs/{event_result.js → EventResult.js} +18 -16
- package/dist/cjs/EventResult.js.map +7 -0
- package/dist/cjs/HTTPEventBridge.d.ts +10 -0
- package/dist/cjs/HTTPEventBridge.js +37 -0
- package/dist/cjs/HTTPEventBridge.js.map +7 -0
- package/dist/cjs/JSONLEventBridge.d.ts +26 -0
- package/dist/cjs/{bridge_jsonl.js → JSONLEventBridge.js} +8 -8
- package/dist/cjs/JSONLEventBridge.js.map +7 -0
- package/dist/cjs/LockManager.d.ts +70 -0
- package/dist/cjs/{lock_manager.js → LockManager.js} +4 -4
- package/dist/cjs/LockManager.js.map +7 -0
- package/dist/cjs/NATSEventBridge.d.ts +20 -0
- package/dist/cjs/{bridge_nats.js → NATSEventBridge.js} +8 -8
- package/dist/cjs/NATSEventBridge.js.map +7 -0
- package/dist/cjs/OtelTracingMiddleware.d.ts +49 -0
- package/dist/cjs/{middleware_otel_tracing.js → OtelTracingMiddleware.js} +49 -26
- package/dist/cjs/OtelTracingMiddleware.js.map +7 -0
- package/dist/cjs/PostgresEventBridge.d.ts +31 -0
- package/dist/cjs/{bridge_postgres.js → PostgresEventBridge.js} +8 -8
- package/dist/cjs/PostgresEventBridge.js.map +7 -0
- package/dist/cjs/RedisEventBridge.d.ts +34 -0
- package/dist/cjs/{bridge_redis.js → RedisEventBridge.js} +8 -8
- package/dist/cjs/RedisEventBridge.js.map +7 -0
- package/dist/cjs/SQLiteEventBridge.d.ts +30 -0
- package/dist/cjs/{bridge_sqlite.js → SQLiteEventBridge.js} +8 -8
- package/dist/cjs/SQLiteEventBridge.js.map +7 -0
- package/dist/cjs/SocketEventBridge.d.ts +4 -0
- package/dist/cjs/SocketEventBridge.js +35 -0
- package/dist/cjs/SocketEventBridge.js.map +7 -0
- package/dist/cjs/bridge_ipc.d.ts +45 -0
- package/dist/cjs/bridges.d.ts +9 -49
- package/dist/cjs/bridges.js +16 -303
- package/dist/cjs/bridges.js.map +2 -2
- package/dist/cjs/events_suck.d.ts +2 -2
- package/dist/cjs/events_suck.js +4 -4
- package/dist/cjs/events_suck.js.map +2 -2
- package/dist/cjs/index.d.ts +15 -14
- package/dist/cjs/index.js +24 -24
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/logging.d.ts +2 -2
- package/dist/cjs/logging.js +7 -7
- package/dist/cjs/logging.js.map +2 -2
- package/dist/cjs/middleware_otel_tracing.d.ts +2 -2
- package/dist/cjs/middlewares.d.ts +1 -13
- package/dist/cjs/middlewares.js.map +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/{base_event.js → BaseEvent.js} +4 -4
- package/dist/esm/BaseEvent.js.map +7 -0
- package/dist/esm/EventBridge.js +275 -0
- package/dist/esm/EventBridge.js.map +7 -0
- package/dist/esm/{event_bus.js → EventBus.js} +5 -5
- package/dist/esm/EventBus.js.map +7 -0
- package/dist/esm/EventBusMiddleware.js +1 -0
- package/dist/esm/EventBusMiddleware.js.map +7 -0
- package/dist/esm/{event_handler.js → EventHandler.js} +1 -1
- package/dist/esm/EventHandler.js.map +7 -0
- package/dist/esm/{event_history.js → EventHistory.js} +1 -1
- package/dist/esm/EventHistory.js.map +7 -0
- package/dist/esm/{event_result.js → EventResult.js} +7 -5
- package/dist/esm/EventResult.js.map +7 -0
- package/dist/esm/HTTPEventBridge.js +17 -0
- package/dist/esm/HTTPEventBridge.js.map +7 -0
- package/dist/esm/{bridge_jsonl.js → JSONLEventBridge.js} +3 -3
- package/dist/esm/JSONLEventBridge.js.map +7 -0
- package/dist/esm/{lock_manager.js → LockManager.js} +1 -1
- package/dist/esm/LockManager.js.map +7 -0
- package/dist/esm/{bridge_nats.js → NATSEventBridge.js} +3 -3
- package/dist/esm/NATSEventBridge.js.map +7 -0
- package/dist/esm/{middleware_otel_tracing.js → OtelTracingMiddleware.js} +47 -24
- package/dist/esm/OtelTracingMiddleware.js.map +7 -0
- package/dist/esm/{bridge_postgres.js → PostgresEventBridge.js} +3 -3
- package/dist/esm/PostgresEventBridge.js.map +7 -0
- package/dist/esm/{bridge_redis.js → RedisEventBridge.js} +3 -3
- package/dist/esm/RedisEventBridge.js.map +7 -0
- package/dist/esm/{bridge_sqlite.js → SQLiteEventBridge.js} +3 -3
- package/dist/esm/SQLiteEventBridge.js.map +7 -0
- package/dist/esm/SocketEventBridge.js +15 -0
- package/dist/esm/SocketEventBridge.js.map +7 -0
- package/dist/esm/bridges.js +9 -296
- package/dist/esm/bridges.js.map +2 -2
- package/dist/esm/events_suck.js +2 -2
- package/dist/esm/events_suck.js.map +1 -1
- package/dist/esm/index.js +11 -19
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/logging.js +2 -2
- package/dist/esm/logging.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/types/BaseEvent.d.ts +211 -0
- package/dist/types/EventBridge.d.ts +34 -0
- package/dist/types/EventBus.d.ts +125 -0
- package/dist/types/EventBusMiddleware.d.ts +13 -0
- package/dist/types/EventHandler.d.ts +140 -0
- package/dist/types/EventHistory.d.ts +45 -0
- package/dist/types/EventResult.d.ts +86 -0
- package/dist/types/HTTPEventBridge.d.ts +10 -0
- package/dist/types/JSONLEventBridge.d.ts +26 -0
- package/dist/types/LockManager.d.ts +70 -0
- package/dist/types/NATSEventBridge.d.ts +20 -0
- package/dist/types/OtelTracingMiddleware.d.ts +49 -0
- package/dist/types/PostgresEventBridge.d.ts +31 -0
- package/dist/types/RedisEventBridge.d.ts +34 -0
- package/dist/types/SQLiteEventBridge.d.ts +30 -0
- package/dist/types/SocketEventBridge.d.ts +4 -0
- package/dist/types/bridge_ipc.d.ts +45 -0
- package/dist/types/bridges.d.ts +9 -49
- package/dist/types/events_suck.d.ts +2 -2
- package/dist/types/index.d.ts +15 -14
- package/dist/types/logging.d.ts +2 -2
- package/dist/types/middleware_otel_tracing.d.ts +2 -2
- package/dist/types/middlewares.d.ts +1 -13
- package/dist/types/types.d.ts +1 -1
- package/package.json +52 -10
- package/src/{base_event.ts → BaseEvent.ts} +5 -5
- package/src/EventBridge.ts +332 -0
- package/src/{event_bus.ts → EventBus.ts} +6 -6
- package/src/EventBusMiddleware.ts +16 -0
- package/src/{event_handler.ts → EventHandler.ts} +2 -2
- package/src/{event_history.ts → EventHistory.ts} +1 -1
- package/src/{event_result.ts → EventResult.ts} +8 -6
- package/src/HTTPEventBridge.ts +27 -0
- package/src/{bridge_jsonl.ts → JSONLEventBridge.ts} +2 -2
- package/src/{lock_manager.ts → LockManager.ts} +2 -2
- package/src/{bridge_nats.ts → NATSEventBridge.ts} +2 -2
- package/src/{middleware_otel_tracing.ts → OtelTracingMiddleware.ts} +55 -26
- package/src/{bridge_postgres.ts → PostgresEventBridge.ts} +2 -2
- package/src/{bridge_redis.ts → RedisEventBridge.ts} +2 -2
- package/src/{bridge_sqlite.ts → SQLiteEventBridge.ts} +2 -2
- package/src/SocketEventBridge.ts +13 -0
- package/src/bridges.ts +9 -376
- package/src/events_suck.ts +2 -2
- package/src/index.ts +15 -22
- package/src/logging.ts +3 -3
- package/src/middlewares.ts +1 -16
- package/src/types.ts +1 -1
- package/dist/cjs/base_event.js.map +0 -7
- package/dist/cjs/bridge_jsonl.js.map +0 -7
- package/dist/cjs/bridge_nats.js.map +0 -7
- package/dist/cjs/bridge_postgres.js.map +0 -7
- package/dist/cjs/bridge_redis.js.map +0 -7
- package/dist/cjs/bridge_sqlite.js.map +0 -7
- package/dist/cjs/event_bus.js.map +0 -7
- package/dist/cjs/event_handler.js.map +0 -7
- package/dist/cjs/event_history.js.map +0 -7
- package/dist/cjs/event_result.js.map +0 -7
- package/dist/cjs/lock_manager.js.map +0 -7
- package/dist/cjs/middleware_otel_tracing.js.map +0 -7
- package/dist/esm/base_event.js.map +0 -7
- package/dist/esm/bridge_jsonl.js.map +0 -7
- package/dist/esm/bridge_nats.js.map +0 -7
- package/dist/esm/bridge_postgres.js.map +0 -7
- package/dist/esm/bridge_redis.js.map +0 -7
- package/dist/esm/bridge_sqlite.js.map +0 -7
- package/dist/esm/event_bus.js.map +0 -7
- package/dist/esm/event_handler.js.map +0 -7
- package/dist/esm/event_history.js.map +0 -7
- package/dist/esm/event_result.js.map +0 -7
- package/dist/esm/lock_manager.js.map +0 -7
- package/dist/esm/middleware_otel_tracing.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/EventHistory.ts"],
|
|
4
|
+
"sourcesContent": ["import { BaseEvent } from './BaseEvent.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
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { v7 as uuidv7 } from "uuid";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { BaseEvent } from "./
|
|
4
|
-
import { EventHandler, EventHandlerCancelledError, EventHandlerResultSchemaError, EventHandlerTimeoutError } from "./
|
|
5
|
-
import { withResolvers } from "./
|
|
3
|
+
import { BaseEvent } from "./BaseEvent.js";
|
|
4
|
+
import { EventHandler, EventHandlerCancelledError, EventHandlerResultSchemaError, EventHandlerTimeoutError } from "./EventHandler.js";
|
|
5
|
+
import { withResolvers } from "./LockManager.js";
|
|
6
6
|
import { isZodSchema } from "./types.js";
|
|
7
7
|
import { _runWithAsyncContext } from "./async_context.js";
|
|
8
8
|
import { RetryTimeoutError } from "./retry.js";
|
|
@@ -74,7 +74,9 @@ class EventResult {
|
|
|
74
74
|
return this.event.event_id;
|
|
75
75
|
}
|
|
76
76
|
get bus() {
|
|
77
|
-
|
|
77
|
+
const original_event = this.event._event_original ?? this.event;
|
|
78
|
+
const dispatch_bus = original_event.event_bus ?? this.event.event_bus;
|
|
79
|
+
return dispatch_bus.all_instances.findBusById(this.handler.eventbus_id) ?? dispatch_bus;
|
|
78
80
|
}
|
|
79
81
|
get handler_id() {
|
|
80
82
|
return this.handler.id;
|
|
@@ -423,4 +425,4 @@ export {
|
|
|
423
425
|
EventResult,
|
|
424
426
|
EventResultJSONSchema
|
|
425
427
|
};
|
|
426
|
-
//# sourceMappingURL=
|
|
428
|
+
//# sourceMappingURL=EventResult.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/EventResult.ts"],
|
|
4
|
+
"sourcesContent": ["import { v7 as uuidv7 } from 'uuid'\n\nimport { z } from 'zod'\n\nimport { BaseEvent } from './BaseEvent.js'\nimport type { EventBus } from './EventBus.js'\nimport { EventHandler, EventHandlerCancelledError, EventHandlerResultSchemaError, EventHandlerTimeoutError } from './EventHandler.js'\nimport { withResolvers, type HandlerLock } from './LockManager.js'\nimport type { Deferred } from './LockManager.js'\nimport type { EventHandlerCallable, EventResultType } from './types.js'\nimport { isZodSchema } from './types.js'\nimport { _runWithAsyncContext } from './async_context.js'\nimport { RetryTimeoutError } from './retry.js'\nimport { _runWithAbortMonitor, _runWithSlowMonitor, _runWithTimeout } from './timing.js'\nimport { monotonicDatetime } from './helpers.js'\n\n// More precise than event.event_status, includes separate 'error' state for handlers that throw errors during execution\nexport type EventResultStatus = 'pending' | 'started' | 'completed' | 'error'\n\nexport const EventResultJSONSchema = z\n .object({\n id: z.string(),\n status: z.enum(['pending', 'started', 'completed', 'error']),\n event_id: z.string(),\n handler_id: z.string(),\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().optional(),\n handler_event_pattern: z.union([z.string(), z.literal('*')]).optional(),\n eventbus_name: z.string(),\n eventbus_id: z.string().uuid(),\n started_at: z.string().datetime().nullable().optional(),\n completed_at: z.string().datetime().nullable().optional(),\n result: z.unknown().optional(),\n error: z.unknown().optional(),\n event_children: z.array(z.string()),\n })\n .strict()\n\nexport type EventResultJSON = z.infer<typeof EventResultJSONSchema>\n\n// Object that tracks the pending or completed execution of a single event handler\nexport class EventResult<TEvent extends BaseEvent = BaseEvent> {\n id: string // unique uuidv7 identifier for the event result\n status: EventResultStatus // 'pending', 'started', 'completed', or 'error'\n event: TEvent // the Event that the handler is processing\n handler: EventHandler // the EventHandler object that going to process the event\n started_at: string | null\n completed_at: string | null\n result?: EventResultType<TEvent> // parsed return value from the event handler\n error?: unknown // error object thrown by the event handler, or null if the handler completed successfully\n event_children: BaseEvent[] // list of emitted child events\n\n // Abort signal: created when handler starts, rejected by _signalAbort() to\n // interrupt runHandler's await via Promise.race.\n _abort: Deferred<never> | null\n // Handler lock: tracks ownership of the handler concurrency lock\n // during handler execution. Set by runHandler(), used by\n // _processEventImmediately for yield-and-reacquire during queue-jumps.\n _lock: HandlerLock | null\n // Runloop pause releases keyed by bus for queue-jump; released when handler exits.\n _queue_jump_pause_releases: Map<EventBus, () => void> | null\n\n constructor(params: { event: TEvent; handler: EventHandler }) {\n this.id = uuidv7()\n this.status = 'pending'\n this.event = params.event\n this.handler = params.handler\n this.started_at = null\n this.completed_at = null\n this.result = undefined\n this.error = undefined\n this.event_children = []\n this._abort = null\n this._lock = null\n this._queue_jump_pause_releases = null\n }\n\n toString(): string {\n return `${this.result ?? 'null'} (${this.status})`\n }\n\n get event_id(): string {\n return this.event.event_id\n }\n\n get bus(): EventBus {\n const original_event = this.event._event_original ?? this.event\n const dispatch_bus = original_event.event_bus ?? this.event.event_bus!\n return dispatch_bus.all_instances.findBusById(this.handler.eventbus_id) ?? dispatch_bus\n }\n\n get handler_id(): string {\n return this.handler.id\n }\n\n get handler_name(): string {\n return this.handler.handler_name\n }\n\n get handler_file_path(): string | null {\n return this.handler.handler_file_path\n }\n\n get eventbus_name(): string {\n return this.handler.eventbus_name\n }\n\n get eventbus_id(): string {\n return this.handler.eventbus_id\n }\n\n get eventbus_label(): string {\n return `${this.handler.eventbus_name}#${this.handler.eventbus_id.slice(-4)}`\n }\n\n private getHookBus(): EventBus | undefined {\n const root_bus = this.event.event_bus\n if (!root_bus) {\n return undefined\n }\n return root_bus.all_instances.findBusById(this.eventbus_id) ?? root_bus\n }\n\n private async _notifyStatusHook(status: 'started' | 'completed'): Promise<void> {\n const hook_bus = this.getHookBus()\n if (!hook_bus) {\n return\n }\n const event_for_hook = hook_bus._getEventProxyScopedToThisBus(this.event._event_original ?? this.event, this)\n await hook_bus.onEventResultChange(event_for_hook, this, status)\n }\n\n // shortcut for the result value so users can do event_result.value instead of event_result.result\n get value(): EventResultType<TEvent> | undefined {\n return this.result\n }\n\n // Per-result schema reference derives from the parent event schema.\n // It is intentionally not serialized with each EventResult to avoid duplication.\n get result_type(): TEvent['event_result_type'] {\n const original_event = this.event._event_original ?? this.event\n return original_event.event_result_type as TEvent['event_result_type']\n }\n\n // Link a child event emitted by this handler run to the parent event/result.\n _linkEmittedChildEvent(child_event: BaseEvent): void {\n const original_child = child_event._event_original ?? child_event\n const parent_event = this.event._event_original ?? this.event\n if (original_child.event_id === parent_event.event_id) {\n return\n }\n if (!original_child.event_parent_id) {\n original_child.event_parent_id = parent_event.event_id\n }\n if (!original_child.event_emitted_by_handler_id) {\n original_child.event_emitted_by_handler_id = this.handler_id\n }\n if (!this.event_children.some((child) => child.event_id === original_child.event_id)) {\n this.event_children.push(original_child)\n }\n }\n\n // Get the raw return value from the handler, even if it threw an error / failed validation\n get raw_value(): EventResultType<TEvent> | undefined {\n if (this.error && (this.error as any).raw_value !== undefined) {\n return (this.error as any).raw_value\n }\n return this.result\n }\n\n // Resolve handler timeout in seconds using precedence: handler -> event -> bus defaults.\n get handler_timeout(): number | null {\n const original = this.event._event_original ?? this.event\n const resolved_event_timeout = original.event_timeout ?? this.bus.event_timeout\n\n let resolved_handler_timeout: number | null\n if (this.handler.handler_timeout !== undefined) {\n resolved_handler_timeout = this.handler.handler_timeout\n } else if (original.event_handler_timeout !== undefined) {\n resolved_handler_timeout = original.event_handler_timeout\n } else {\n resolved_handler_timeout = this.bus.event_timeout\n }\n\n if (resolved_handler_timeout === null && resolved_event_timeout === null) {\n return null\n }\n if (resolved_handler_timeout === null) {\n return resolved_event_timeout\n }\n if (resolved_event_timeout === null) {\n return resolved_handler_timeout\n }\n return Math.min(resolved_handler_timeout, resolved_event_timeout)\n }\n\n // Resolve slow handler warning threshold in seconds using precedence: handler -> event -> bus defaults.\n get handler_slow_timeout(): number | null {\n const original = this.event._event_original ?? this.event\n\n if (this.handler.handler_slow_timeout !== undefined) {\n return this.handler.handler_slow_timeout\n }\n if (original.event_handler_slow_timeout !== undefined) {\n return original.event_handler_slow_timeout\n }\n const event_slow_timeout = (original as { event_slow_timeout?: number | null }).event_slow_timeout\n if (event_slow_timeout !== undefined) {\n return event_slow_timeout\n }\n if (this.bus?.event_handler_slow_timeout !== undefined) {\n return this.bus.event_handler_slow_timeout\n }\n return this.bus?.event_slow_timeout ?? null\n }\n\n // Create a slow-handler warning timer that logs if the handler runs too long.\n _createSlowHandlerWarningTimer(effective_timeout: number | null): ReturnType<typeof setTimeout> | null {\n const handler_warn_timeout = this.handler_slow_timeout\n const warn_ms = handler_warn_timeout === null ? null : handler_warn_timeout * 1000\n const should_warn = warn_ms !== null && (effective_timeout === null || effective_timeout * 1000 > warn_ms)\n if (!should_warn || warn_ms === null) {\n return null\n }\n const event = this.event._event_original ?? this.event\n const bus_name = this.handler.eventbus_name\n const started_at_ms = performance.now()\n return setTimeout(() => {\n if (this.status !== 'started') {\n return\n }\n const elapsed_ms = performance.now() - started_at_ms\n const elapsed_seconds = (elapsed_ms / 1000).toFixed(1)\n console.warn(\n `[abxbus] Slow event handler: ${bus_name}.on(${event.toString()}, ${this.handler.toString()}) still running after ${elapsed_seconds}s`\n )\n }, warn_ms)\n }\n\n _ensureQueueJumpPause(bus: EventBus): void {\n if (!this._queue_jump_pause_releases) {\n this._queue_jump_pause_releases = new Map()\n }\n if (this._queue_jump_pause_releases.has(bus)) {\n return\n }\n this._queue_jump_pause_releases.set(bus, bus.locks._requestRunloopPause())\n }\n\n _releaseQueueJumpPauses(): void {\n if (!this._queue_jump_pause_releases) {\n return\n }\n for (const release of this._queue_jump_pause_releases.values()) {\n release()\n }\n this._queue_jump_pause_releases.clear()\n }\n\n update(params: { status?: EventResultStatus; result?: EventResultType<TEvent> | BaseEvent | undefined; error?: unknown }): this {\n const has_status = 'status' in params\n const has_result = 'result' in params\n const has_error = 'error' in params\n\n if (has_result) {\n const raw_result = params.result\n this.status = 'completed'\n if (\n this.event.event_result_type &&\n raw_result !== undefined &&\n !(raw_result instanceof BaseEvent) &&\n isZodSchema(this.event.event_result_type)\n ) {\n const parsed = this.event.event_result_type.safeParse(raw_result)\n if (parsed.success) {\n this.result = parsed.data as EventResultType<TEvent>\n } else {\n const error = new EventHandlerResultSchemaError(\n `Event handler return value ${JSON.stringify(raw_result).slice(0, 20)}... did not match event_result_type: ${parsed.error.message}`,\n { event_result: this, cause: parsed.error, raw_value: raw_result }\n )\n this.error = error\n this.result = undefined\n this.status = 'error'\n }\n } else {\n this.result = raw_result as EventResultType<TEvent> | undefined\n }\n }\n\n if (has_error) {\n this.error = params.error\n this.status = 'error'\n }\n\n if (has_status && params.status !== undefined) {\n this.status = params.status\n }\n\n if (this.status !== 'pending' && this.started_at === null) {\n this.started_at = monotonicDatetime()\n }\n if ((this.status === 'completed' || this.status === 'error') && this.completed_at === null) {\n this.completed_at = monotonicDatetime()\n }\n\n return this\n }\n\n private _createHandlerTimeoutError(event: BaseEvent): EventHandlerTimeoutError {\n return new EventHandlerTimeoutError(\n `${this.bus.toString()}.on(${event.toString()}, ${this.handler.toString()}) timed out after ${this.handler_timeout}s`,\n {\n event_result: this,\n timeout_seconds: this.handler_timeout,\n }\n )\n }\n\n private _handleHandlerError(event: BaseEvent, error: unknown): void {\n const normalized_error =\n error instanceof RetryTimeoutError\n ? new EventHandlerTimeoutError(error.message, { event_result: this, timeout_seconds: error.timeout_seconds, cause: error })\n : error\n if (normalized_error instanceof EventHandlerTimeoutError) {\n this._markError(normalized_error, false)\n event._cancelPendingChildProcessing(normalized_error)\n } else {\n this._markError(normalized_error, false)\n }\n }\n\n private _onHandlerExit(slow_handler_warning_timer: ReturnType<typeof setTimeout> | null): void {\n this._abort = null\n this._lock = null\n this._releaseQueueJumpPauses()\n if (slow_handler_warning_timer) {\n clearTimeout(slow_handler_warning_timer)\n }\n }\n\n // Run one handler invocation with timeout/slow-monitor/error handling.\n // Handler lock acquisition is owned by BaseEvent._runHandlers(...).\n async runHandler(handler_lock: HandlerLock | null): Promise<void> {\n if (this.status === 'error' && this.error instanceof EventHandlerCancelledError) {\n return\n }\n\n const event = this.event._event_original ?? this.event\n const handler_event = this.bus._getEventProxyScopedToThisBus(event, this)\n if (this._lock) {\n this._lock.exitHandlerRun()\n }\n\n let slow_handler_warning_timer: ReturnType<typeof setTimeout> | null = null\n // if the result is already in an error or completed state, exit early\n if (this.status === 'error' || this.status === 'completed') {\n return\n }\n\n this._lock = handler_lock\n await this.bus.locks._runWithHandlerDispatchContext(this, async () => {\n await _runWithAsyncContext(event._getDispatchContext() ?? null, async () => {\n try {\n const should_notify_started = this.status === 'pending'\n const abort_signal = this._markStarted(false)\n if (should_notify_started) {\n await this._notifyStatusHook('started')\n }\n slow_handler_warning_timer = this._createSlowHandlerWarningTimer(this.handler_timeout)\n const handler_result = await _runWithTimeout(\n this.handler_timeout,\n () => this._createHandlerTimeoutError(event),\n () =>\n _runWithSlowMonitor(slow_handler_warning_timer, () =>\n _runWithAbortMonitor(() => this.handler._handler_async(handler_event), abort_signal)\n )\n )\n this._markCompleted(handler_result as EventResultType<TEvent> | BaseEvent | undefined, false)\n } catch (error) {\n this._handleHandlerError(event, error)\n } finally {\n if (this.status === 'completed' || this.status === 'error') {\n await this._notifyStatusHook('completed')\n }\n this._onHandlerExit(slow_handler_warning_timer)\n }\n })\n })\n }\n\n // Reject the abort promise, causing runHandler's Promise.race to\n // throw immediately \u2014 even if the handler has no timeout.\n _signalAbort(error: Error): void {\n if (this._abort) {\n this._abort.reject(error)\n this._abort = null\n }\n }\n\n // Mark started and return the abort promise for Promise.race.\n _markStarted(notify_hook: boolean = true): Promise<never> {\n if (!this._abort) {\n this._abort = withResolvers<never>()\n }\n if (this.status === 'pending') {\n this.update({ status: 'started' })\n if (notify_hook) {\n void this._notifyStatusHook('started')\n }\n }\n return this._abort.promise\n }\n\n _markCompleted(result: EventResultType<TEvent> | BaseEvent | undefined, notify_hook: boolean = true): void {\n if (this.status === 'completed' || this.status === 'error') return\n this.update({ result })\n if (notify_hook) {\n void this._notifyStatusHook('completed')\n }\n }\n\n _markError(error: unknown, notify_hook: boolean = true): void {\n if (this.status === 'completed' || this.status === 'error') return\n this.update({ error })\n if (notify_hook) {\n void this._notifyStatusHook('completed')\n }\n }\n\n toJSON(): EventResultJSON {\n return {\n id: this.id,\n status: this.status,\n event_id: this.event.event_id,\n handler_id: this.handler_id,\n handler_name: this.handler_name,\n handler_file_path: this.handler_file_path,\n handler_timeout: this.handler.handler_timeout,\n handler_slow_timeout: this.handler.handler_slow_timeout,\n handler_registered_at: this.handler.handler_registered_at,\n handler_event_pattern: this.handler.event_pattern,\n eventbus_name: this.eventbus_name,\n eventbus_id: this.eventbus_id,\n started_at: this.started_at,\n completed_at: this.completed_at,\n result: this.result,\n error: this.error,\n event_children: this.event_children.map((child) => child.event_id),\n }\n }\n\n static fromJSON<TEvent extends BaseEvent>(event: TEvent, data: unknown): EventResult<TEvent> {\n const record = EventResultJSONSchema.parse(data)\n const handler_record = {\n id: record.handler_id,\n eventbus_name: record.eventbus_name,\n eventbus_id: record.eventbus_id,\n event_pattern: record.handler_event_pattern ?? event.event_type,\n handler_name: record.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 ?? event.event_created_at,\n } as const\n const handler_stub = EventHandler.fromJSON(handler_record, (() => undefined) as EventHandlerCallable)\n\n const result = new EventResult<TEvent>({ event, handler: handler_stub })\n result.id = record.id\n result.status = record.status\n result.started_at = record.started_at === null || record.started_at === undefined ? null : monotonicDatetime(record.started_at)\n result.completed_at = record.completed_at === null || record.completed_at === undefined ? null : monotonicDatetime(record.completed_at)\n if ('result' in record) {\n result.result = record.result as EventResultType<TEvent>\n }\n if ('error' in record) {\n result.error = record.error\n }\n result.event_children = []\n return result\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventBridge, parseEndpoint, randomSuffix } from "./EventBridge.js";
|
|
2
|
+
class HTTPEventBridge extends EventBridge {
|
|
3
|
+
constructor(send_to_or_options, listen_on, name) {
|
|
4
|
+
const options = typeof send_to_or_options === "object" ? send_to_or_options ?? {} : { send_to: send_to_or_options ?? void 0, listen_on: listen_on ?? void 0, name };
|
|
5
|
+
if (options.send_to && parseEndpoint(options.send_to).scheme === "unix") {
|
|
6
|
+
throw new Error("HTTPEventBridge send_to must be http:// or https://");
|
|
7
|
+
}
|
|
8
|
+
if (options.listen_on && parseEndpoint(options.listen_on).scheme !== "http") {
|
|
9
|
+
throw new Error("HTTPEventBridge listen_on must be http://");
|
|
10
|
+
}
|
|
11
|
+
super(options.send_to, options.listen_on, options.name ?? `HTTPEventBridge_${randomSuffix()}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
HTTPEventBridge
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=HTTPEventBridge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/HTTPEventBridge.ts"],
|
|
4
|
+
"sourcesContent": ["import { EventBridge, parseEndpoint, randomSuffix } from './EventBridge.js'\n\nexport type HTTPEventBridgeOptions = {\n send_to?: string | null\n listen_on?: string | null\n name?: string\n}\n\nexport class HTTPEventBridge extends EventBridge {\n constructor(send_to?: string | null, listen_on?: string | null, name?: string)\n constructor(options?: HTTPEventBridgeOptions)\n constructor(send_to_or_options?: string | null | HTTPEventBridgeOptions, listen_on?: string | null, name?: string) {\n const options: HTTPEventBridgeOptions =\n typeof send_to_or_options === 'object'\n ? (send_to_or_options ?? {})\n : { send_to: send_to_or_options ?? undefined, listen_on: listen_on ?? undefined, name }\n\n if (options.send_to && parseEndpoint(options.send_to).scheme === 'unix') {\n throw new Error('HTTPEventBridge send_to must be http:// or https://')\n }\n if (options.listen_on && parseEndpoint(options.listen_on).scheme !== 'http') {\n throw new Error('HTTPEventBridge listen_on must be http://')\n }\n\n super(options.send_to, options.listen_on, options.name ?? `HTTPEventBridge_${randomSuffix()}`)\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa,eAAe,oBAAoB;AAQlD,MAAM,wBAAwB,YAAY;AAAA,EAG/C,YAAY,oBAA6D,WAA2B,MAAe;AACjH,UAAM,UACJ,OAAO,uBAAuB,WACzB,sBAAsB,CAAC,IACxB,EAAE,SAAS,sBAAsB,QAAW,WAAW,aAAa,QAAW,KAAK;AAE1F,QAAI,QAAQ,WAAW,cAAc,QAAQ,OAAO,EAAE,WAAW,QAAQ;AACvE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AACA,QAAI,QAAQ,aAAa,cAAc,QAAQ,SAAS,EAAE,WAAW,QAAQ;AAC3E,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAEA,UAAM,QAAQ,SAAS,QAAQ,WAAW,QAAQ,QAAQ,mBAAmB,aAAa,CAAC,EAAE;AAAA,EAC/F;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseEvent } from "./
|
|
2
|
-
import { EventBus } from "./
|
|
1
|
+
import { BaseEvent } from "./BaseEvent.js";
|
|
2
|
+
import { EventBus } from "./EventBus.js";
|
|
3
3
|
const isNodeRuntime = () => {
|
|
4
4
|
const maybe_process = globalThis.process;
|
|
5
5
|
return typeof maybe_process?.versions?.node === "string";
|
|
@@ -147,4 +147,4 @@ class JSONLEventBridge {
|
|
|
147
147
|
export {
|
|
148
148
|
JSONLEventBridge
|
|
149
149
|
};
|
|
150
|
-
//# sourceMappingURL=
|
|
150
|
+
//# sourceMappingURL=JSONLEventBridge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/JSONLEventBridge.ts"],
|
|
4
|
+
"sourcesContent": ["import { BaseEvent } from './BaseEvent.js'\nimport { EventBus } from './EventBus.js'\nimport type { EventClass, EventHandlerCallable, EventPattern, UntypedEventHandlerFunction } from './types.js'\n\nconst isNodeRuntime = (): boolean => {\n const maybe_process = (globalThis as { process?: { versions?: { node?: string } } }).process\n return typeof maybe_process?.versions?.node === 'string'\n}\n\nconst importNodeModule = async (specifier: string): Promise<any> => {\n const dynamic_import = Function('module_name', 'return import(module_name)') as (module_name: string) => Promise<unknown>\n return dynamic_import(specifier) as Promise<any>\n}\n\nconst randomSuffix = (): string => Math.random().toString(36).slice(2, 10)\n\nexport class JSONLEventBridge {\n readonly path: string\n readonly poll_interval: number\n readonly name: string\n\n private readonly inbound_bus: EventBus\n private running: boolean\n private byte_offset: number\n private pending_line: string\n private listener_task: Promise<void> | null\n\n constructor(path: string, poll_interval: number = 0.25, name?: string) {\n this.path = path\n this.poll_interval = poll_interval\n this.name = name ?? `JSONLEventBridge_${randomSuffix()}`\n this.inbound_bus = new EventBus(this.name, { max_history_size: 0 })\n this.running = false\n this.byte_offset = 0\n this.pending_line = ''\n this.listener_task = null\n\n this.dispatch = this.dispatch.bind(this)\n this.emit = this.emit.bind(this)\n this.on = this.on.bind(this)\n }\n\n on<T extends BaseEvent>(event_pattern: EventClass<T>, handler: EventHandlerCallable<T>): void\n on<T extends BaseEvent>(event_pattern: string | '*', handler: UntypedEventHandlerFunction<T>): void\n on(event_pattern: EventPattern | '*', handler: EventHandlerCallable | UntypedEventHandlerFunction): void {\n this.ensureStarted()\n if (typeof event_pattern === 'string') {\n this.inbound_bus.on(event_pattern, handler as UntypedEventHandlerFunction<BaseEvent>)\n return\n }\n this.inbound_bus.on(event_pattern as EventClass<BaseEvent>, handler as EventHandlerCallable<BaseEvent>)\n }\n\n async emit<T extends BaseEvent>(event: T): Promise<void> {\n this.ensureStarted()\n const fs = await this.loadFs()\n await fs.promises.mkdir(this.dirname(this.path), { recursive: true })\n const payload = JSON.stringify(event.toJSON()) + '\\n'\n await fs.promises.appendFile(this.path, payload, 'utf8')\n }\n\n async dispatch<T extends BaseEvent>(event: T): Promise<void> {\n return this.emit(event)\n }\n\n async start(): Promise<void> {\n if (this.running) return\n const fs = await this.loadFs()\n await fs.promises.mkdir(this.dirname(this.path), { recursive: true })\n await fs.promises.appendFile(this.path, '', 'utf8')\n const stats = await fs.promises.stat(this.path)\n this.byte_offset = Number(stats.size ?? 0)\n this.pending_line = ''\n this.running = true\n this.listener_task = this.listenLoop()\n }\n\n async close(): Promise<void> {\n this.running = false\n await Promise.allSettled(this.listener_task ? [this.listener_task] : [])\n this.listener_task = null\n this.inbound_bus.destroy()\n }\n\n private ensureStarted(): void {\n if (this.running || this.listener_task) return\n void this.start().catch((error: unknown) => {\n console.error('[abxbus] JSONLEventBridge failed to start', error)\n })\n }\n\n private async listenLoop(): Promise<void> {\n while (this.running) {\n try {\n await this.pollNewLines()\n } catch {\n // Keep polling on transient errors.\n }\n await new Promise((resolve) => setTimeout(resolve, Math.max(1, this.poll_interval * 1000)))\n }\n }\n\n private async pollNewLines(): Promise<void> {\n const previous_offset = this.byte_offset\n const { chunk, next_offset } = await this.readAppended(previous_offset)\n this.byte_offset = next_offset\n if (next_offset < previous_offset) {\n this.pending_line = ''\n }\n if (!chunk) return\n\n const new_lines = (this.pending_line + chunk).split('\\n')\n this.pending_line = new_lines.pop() ?? ''\n\n for (const line of new_lines) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n const payload = JSON.parse(trimmed)\n await this.dispatchInboundPayload(payload)\n } catch {\n // Ignore malformed line.\n }\n }\n }\n\n private async dispatchInboundPayload(payload: unknown): Promise<void> {\n const event = BaseEvent.fromJSON(payload).eventReset()\n this.inbound_bus.emit(event)\n }\n\n private async readAppended(offset: number): Promise<{ chunk: string; next_offset: number }> {\n const fs = await this.loadFs()\n let size = 0\n try {\n const stats = await fs.promises.stat(this.path)\n size = Number(stats.size ?? 0)\n } catch (error: unknown) {\n const code = (error as { code?: string }).code\n if (code === 'ENOENT') {\n return { chunk: '', next_offset: 0 }\n }\n throw error\n }\n\n const start_offset = size < offset ? 0 : offset\n if (size === start_offset) {\n return { chunk: '', next_offset: size }\n }\n\n const handle = await fs.promises.open(this.path, 'r')\n try {\n const byte_count = size - start_offset\n const bytes = new Uint8Array(byte_count)\n const { bytesRead } = await handle.read(bytes, 0, byte_count, start_offset)\n const chunk = new TextDecoder().decode(bytes.subarray(0, Number(bytesRead ?? 0)))\n return { chunk, next_offset: start_offset + Number(bytesRead ?? 0) }\n } finally {\n await handle.close()\n }\n }\n\n private dirname(path: string): string {\n const idx = path.lastIndexOf('/')\n return idx >= 0 ? path.slice(0, idx) || '.' : '.'\n }\n\n private async loadFs(): Promise<any> {\n if (!isNodeRuntime()) {\n throw new Error('JSONLEventBridge is only supported in Node.js runtimes')\n }\n return importNodeModule('node:fs')\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/LockManager.ts"],
|
|
4
|
+
"sourcesContent": ["import type { BaseEvent } from './BaseEvent.js'\nimport type { EventResult } from './EventResult.js'\nimport { createAsyncLocalStorage, type AsyncLocalStorageLike } from './async_context.js'\n\n// \u2500\u2500\u2500 Deferred / withResolvers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type Deferred<T> = {\n promise: Promise<T>\n resolve: (value: T | PromiseLike<T>) => void\n reject: (reason?: unknown) => void\n}\n\nexport const withResolvers = <T>(): Deferred<T> => {\n if (typeof Promise.withResolvers === 'function') {\n return Promise.withResolvers<T>()\n }\n let resolve!: (value: T | PromiseLike<T>) => void\n let reject!: (reason?: unknown) => void\n const promise = new Promise<T>((resolve_fn, reject_fn) => {\n resolve = resolve_fn\n reject = reject_fn\n })\n return { promise, resolve, reject }\n}\n\n// \u2500\u2500\u2500 Concurrency modes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const EVENT_CONCURRENCY_MODES = ['global-serial', 'bus-serial', 'parallel'] as const\nexport type EventConcurrencyMode = (typeof EVENT_CONCURRENCY_MODES)[number]\n\nexport const EVENT_HANDLER_CONCURRENCY_MODES = ['serial', 'parallel'] as const\nexport type EventHandlerConcurrencyMode = (typeof EVENT_HANDLER_CONCURRENCY_MODES)[number]\n\nexport const EVENT_HANDLER_COMPLETION_MODES = ['all', 'first'] as const\nexport type EventHandlerCompletionMode = (typeof EVENT_HANDLER_COMPLETION_MODES)[number]\n\n// \u2500\u2500\u2500 AsyncLock \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class AsyncLock {\n size: number\n in_use: number\n waiters: Array<() => void>\n\n constructor(size: number) {\n this.size = size\n this.in_use = 0\n this.waiters = []\n }\n\n async acquire(): Promise<void> {\n if (this.size === Infinity) {\n return\n }\n if (this.in_use < this.size) {\n this.in_use += 1\n return\n }\n await new Promise<void>((resolve) => {\n this.waiters.push(resolve)\n })\n }\n\n release(): void {\n if (this.size === Infinity) {\n return\n }\n const next = this.waiters.shift()\n if (next) {\n // Handoff: keep permit accounted for and transfer directly to next waiter.\n next()\n return\n }\n this.in_use = Math.max(0, this.in_use - 1)\n }\n}\n\nexport const runWithLock = async <T>(lock: AsyncLock | null, fn: () => Promise<T>): Promise<T> => {\n if (!lock) {\n return await fn()\n }\n await lock.acquire()\n try {\n return await fn()\n } finally {\n lock.release()\n }\n}\n\nconst handler_context_storage: AsyncLocalStorageLike | null = createAsyncLocalStorage()\n\n// \u2500\u2500\u2500 HandlerLock \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type HandlerExecutionState = 'held' | 'yielded' | 'closed'\n\n// Tracks a single handler execution's ownership of a handler lock.\n// Reacquire is race-safe: if the handler exits while waiting to reclaim,\n// the reclaimed lock is immediately released to avoid leaks.\nexport class HandlerLock {\n private lock: AsyncLock | null\n private state: HandlerExecutionState\n\n constructor(lock: AsyncLock | null) {\n this.lock = lock\n this.state = 'held'\n }\n\n // used by EventBus._processEventImmediately to yield the parent handler's lock to the child event so it can be processed immediately\n yieldHandlerLockForChildRun(): boolean {\n if (!this.lock || this.state !== 'held') {\n return false\n }\n this.state = 'yielded'\n this.lock.release()\n return true\n }\n\n // used by EventBus._processEventImmediately to reacquire the handler lock after the child event has been processed\n async reclaimHandlerLockIfRunning(): Promise<boolean> {\n if (!this.lock || this.state !== 'yielded') {\n return false\n }\n await this.lock.acquire()\n if (this.state !== 'yielded') {\n // Handler exited while this reacquire was pending.\n this.lock.release()\n return false\n }\n this.state = 'held'\n return true\n }\n\n // used by EventResult.runHandler to exit the handler lock after the handler has finished executing\n exitHandlerRun(): void {\n if (this.state === 'closed') {\n return\n }\n const should_release = !!this.lock && this.state === 'held'\n this.state = 'closed'\n if (should_release) {\n this.lock!.release()\n }\n }\n\n // used by EventBus._processEventImmediately to yield the handler lock and reacquire it after the child event has been processed\n async runQueueJump<T>(fn: () => Promise<T>): Promise<T> {\n const yielded = this.yieldHandlerLockForChildRun()\n try {\n return await fn()\n } finally {\n if (yielded) {\n await this.reclaimHandlerLockIfRunning()\n }\n }\n }\n}\n\n// \u2500\u2500\u2500 LockManager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Interface that must be implemented by the EventBus class to be used by the LockManager\nexport type EventBusInterfaceForLockManager = {\n isIdleAndQueueEmpty: () => boolean\n event_concurrency: EventConcurrencyMode\n _lock_for_event_global_serial: AsyncLock\n}\n\nexport type LockManagerOptions = {\n auto_schedule_idle_checks?: boolean\n}\n\n// The LockManager is responsible for managing the concurrency of events and handlers\nexport class LockManager {\n private bus: EventBusInterfaceForLockManager // Live bus reference; used to read defaults and idle state.\n private auto_schedule_idle_checks: boolean\n\n readonly bus_event_lock: AsyncLock // Per-bus event lock; created with LockManager and never swapped.\n private pause_depth: number // Re-entrant pause counter; increments on _requestRunloopPause, decrements on release.\n private pause_waiters: Array<() => void> // Resolvers for _waitUntilRunloopResumed; drained when pause_depth hits 0.\n private active_handler_results: EventResult[] // Stack of active handler results for \"inside handler\" detection.\n\n private idle_waiters: Array<(became_idle: boolean) => void> // Resolvers waiting for stable idle; cleared when idle confirmed.\n private idle_check_pending: boolean // Debounce flag to avoid scheduling redundant idle checks.\n private idle_check_streak: number // Counts consecutive idle checks; used to require two ticks of idle.\n\n constructor(bus: EventBusInterfaceForLockManager, options: LockManagerOptions = {}) {\n this.bus = bus\n this.auto_schedule_idle_checks = options.auto_schedule_idle_checks ?? true\n this.bus_event_lock = new AsyncLock(1) // used for the bus-serial concurrency mode\n\n this.pause_depth = 0\n this.pause_waiters = []\n this.active_handler_results = []\n\n this.idle_waiters = []\n this.idle_check_pending = false\n this.idle_check_streak = 0\n }\n\n // Low-level runloop pause: increments a re-entrant counter and returns a release\n // function. Used for broad, bus-scoped pauses during queue-jump across buses.\n _requestRunloopPause(): () => void {\n this.pause_depth += 1\n let released = false\n return () => {\n if (released) {\n return\n }\n released = true\n this.pause_depth = Math.max(0, this.pause_depth - 1)\n if (this.pause_depth !== 0) {\n return\n }\n const waiters = this.pause_waiters\n this.pause_waiters = []\n for (const resolve of waiters) {\n resolve()\n }\n }\n }\n\n _waitUntilRunloopResumed(): Promise<void> {\n if (this.pause_depth === 0) {\n return Promise.resolve()\n }\n return new Promise((resolve) => {\n this.pause_waiters.push(resolve)\n })\n }\n\n _isPaused(): boolean {\n return this.pause_depth > 0\n }\n\n async _runWithHandlerDispatchContext<T>(result: EventResult, fn: () => Promise<T>): Promise<T> {\n this.active_handler_results.push(result)\n try {\n if (!handler_context_storage) {\n return await fn()\n }\n return await handler_context_storage.run(result, fn)\n } finally {\n const idx = this.active_handler_results.indexOf(result)\n if (idx >= 0) {\n this.active_handler_results.splice(idx, 1)\n }\n }\n }\n\n _getActiveHandlerResultForCurrentAsyncContext(): EventResult | undefined {\n const result = handler_context_storage?.getStore() as EventResult | undefined\n return result?.status === 'started' ? result : undefined\n }\n\n _getActiveHandlerResults(): EventResult[] {\n return [...this.active_handler_results]\n }\n\n // Per-bus check: true only if this specific bus has a handler on its stack.\n _isAnyHandlerActive(): boolean {\n return this.active_handler_results.length > 0\n }\n\n waitForIdle(timeout_seconds: number | null = null): Promise<boolean> {\n return new Promise((resolve) => {\n let done = false\n let timeout_id: ReturnType<typeof setTimeout> | null = null\n\n const finish = (became_idle: boolean): void => {\n if (done) {\n return\n }\n done = true\n if (timeout_id !== null) {\n clearTimeout(timeout_id)\n timeout_id = null\n }\n resolve(became_idle)\n }\n\n this.idle_waiters.push(finish)\n this.scheduleIdleCheck()\n\n if (timeout_seconds === null || timeout_seconds === undefined) {\n return\n }\n\n const timeout_ms = Math.max(0, Number(timeout_seconds)) * 1000\n if (!Number.isFinite(timeout_ms)) {\n return\n }\n\n timeout_id = setTimeout(() => {\n const index = this.idle_waiters.indexOf(finish)\n if (index >= 0) {\n this.idle_waiters.splice(index, 1)\n }\n finish(false)\n }, timeout_ms)\n })\n }\n\n // Called by EventBus.markEventCompleted and EventBus.markHandlerCompleted to notify\n // waitUntilIdle() callers that the bus may now be idle.\n _notifyIdleListeners(): void {\n // Fast-path: most completions have no waitUntilIdle() callers waiting,\n // so skip expensive idle snapshot scans in that common case.\n if (this.idle_waiters.length === 0) {\n this.idle_check_streak = 0\n return\n }\n\n if (!this.bus.isIdleAndQueueEmpty()) {\n this.idle_check_streak = 0\n if (this.idle_waiters.length > 0) {\n this.scheduleIdleCheck()\n }\n return\n }\n\n this.idle_check_streak += 1\n if (this.idle_check_streak < 2) {\n if (this.idle_waiters.length > 0) {\n this.scheduleIdleCheck()\n }\n return\n }\n\n this.idle_check_streak = 0\n const waiters = this.idle_waiters\n this.idle_waiters = []\n for (const resolve of waiters) {\n resolve(true)\n }\n }\n\n // get the bus-level lock that prevents/allows multiple events to be processed concurrently on the same bus\n getLockForEvent(event: BaseEvent): AsyncLock | null {\n const resolved = event.event_concurrency ?? this.bus.event_concurrency\n if (resolved === 'parallel') {\n return null\n }\n if (resolved === 'global-serial') {\n return this.bus._lock_for_event_global_serial\n }\n return this.bus_event_lock\n }\n\n async _runWithEventLock<T>(\n event: BaseEvent,\n fn: () => Promise<T>,\n options: { bypass_event_locks?: boolean; pre_acquired_lock?: AsyncLock | null } = {}\n ): Promise<T> {\n const pre_acquired = options.pre_acquired_lock ?? null\n if (options.bypass_event_locks || pre_acquired) {\n return await fn()\n }\n return await runWithLock(this.getLockForEvent(event), fn)\n }\n\n async _runWithHandlerLock<T>(\n event: BaseEvent,\n default_handler_concurrency: EventHandlerConcurrencyMode | undefined,\n fn: (lock: HandlerLock | null) => Promise<T>\n ): Promise<T> {\n const lock = event._getHandlerLock(default_handler_concurrency)\n if (lock) {\n await lock.acquire()\n }\n const handler_lock = lock ? new HandlerLock(lock) : null\n try {\n return await fn(handler_lock)\n } finally {\n handler_lock?.exitHandlerRun()\n }\n }\n\n // Schedules a debounced idle check to run after a short delay. Used to gate\n // waitUntilIdle() calls during handler execution and after event completion.\n private scheduleIdleCheck(): void {\n if (!this.auto_schedule_idle_checks) {\n return\n }\n if (this.idle_check_pending) {\n return\n }\n this.idle_check_pending = true\n setTimeout(() => {\n this.idle_check_pending = false\n this._notifyIdleListeners()\n }, 0)\n }\n\n // Reset all state to initial values\n clear(): void {\n this.pause_depth = 0\n this.pause_waiters = []\n this.active_handler_results = []\n this.idle_waiters = []\n this.idle_check_pending = false\n this.idle_check_streak = 0\n }\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,+BAA2D;AAU7D,MAAM,gBAAgB,MAAsB;AACjD,MAAI,OAAO,QAAQ,kBAAkB,YAAY;AAC/C,WAAO,QAAQ,cAAiB;AAAA,EAClC;AACA,MAAI;AACJ,MAAI;AACJ,QAAM,UAAU,IAAI,QAAW,CAAC,YAAY,cAAc;AACxD,cAAU;AACV,aAAS;AAAA,EACX,CAAC;AACD,SAAO,EAAE,SAAS,SAAS,OAAO;AACpC;AAIO,MAAM,0BAA0B,CAAC,iBAAiB,cAAc,UAAU;AAG1E,MAAM,kCAAkC,CAAC,UAAU,UAAU;AAG7D,MAAM,iCAAiC,CAAC,OAAO,OAAO;AAKtD,MAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,MAAc;AACxB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU,CAAC;AAAA,EAClB;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,SAAS,UAAU;AAC1B;AAAA,IACF;AACA,QAAI,KAAK,SAAS,KAAK,MAAM;AAC3B,WAAK,UAAU;AACf;AAAA,IACF;AACA,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,WAAK,QAAQ,KAAK,OAAO;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,SAAS,UAAU;AAC1B;AAAA,IACF;AACA,UAAM,OAAO,KAAK,QAAQ,MAAM;AAChC,QAAI,MAAM;AAER,WAAK;AACL;AAAA,IACF;AACA,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC;AAAA,EAC3C;AACF;AAEO,MAAM,cAAc,OAAU,MAAwB,OAAqC;AAChG,MAAI,CAAC,MAAM;AACT,WAAO,MAAM,GAAG;AAAA,EAClB;AACA,QAAM,KAAK,QAAQ;AACnB,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,SAAK,QAAQ;AAAA,EACf;AACF;AAEA,MAAM,0BAAwD,wBAAwB;AAS/E,MAAM,YAAY;AAAA,EACf;AAAA,EACA;AAAA,EAER,YAAY,MAAwB;AAClC,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA,EAGA,8BAAuC;AACrC,QAAI,CAAC,KAAK,QAAQ,KAAK,UAAU,QAAQ;AACvC,aAAO;AAAA,IACT;AACA,SAAK,QAAQ;AACb,SAAK,KAAK,QAAQ;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,8BAAgD;AACpD,QAAI,CAAC,KAAK,QAAQ,KAAK,UAAU,WAAW;AAC1C,aAAO;AAAA,IACT;AACA,UAAM,KAAK,KAAK,QAAQ;AACxB,QAAI,KAAK,UAAU,WAAW;AAE5B,WAAK,KAAK,QAAQ;AAClB,aAAO;AAAA,IACT;AACA,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,iBAAuB;AACrB,QAAI,KAAK,UAAU,UAAU;AAC3B;AAAA,IACF;AACA,UAAM,iBAAiB,CAAC,CAAC,KAAK,QAAQ,KAAK,UAAU;AACrD,SAAK,QAAQ;AACb,QAAI,gBAAgB;AAClB,WAAK,KAAM,QAAQ;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAgB,IAAkC;AACtD,UAAM,UAAU,KAAK,4BAA4B;AACjD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,UAAE;AACA,UAAI,SAAS;AACX,cAAM,KAAK,4BAA4B;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;AAgBO,MAAM,YAAY;AAAA,EACf;AAAA;AAAA,EACA;AAAA,EAEC;AAAA;AAAA,EACD;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EAER,YAAY,KAAsC,UAA8B,CAAC,GAAG;AAClF,SAAK,MAAM;AACX,SAAK,4BAA4B,QAAQ,6BAA6B;AACtE,SAAK,iBAAiB,IAAI,UAAU,CAAC;AAErC,SAAK,cAAc;AACnB,SAAK,gBAAgB,CAAC;AACtB,SAAK,yBAAyB,CAAC;AAE/B,SAAK,eAAe,CAAC;AACrB,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA,EAIA,uBAAmC;AACjC,SAAK,eAAe;AACpB,QAAI,WAAW;AACf,WAAO,MAAM;AACX,UAAI,UAAU;AACZ;AAAA,MACF;AACA,iBAAW;AACX,WAAK,cAAc,KAAK,IAAI,GAAG,KAAK,cAAc,CAAC;AACnD,UAAI,KAAK,gBAAgB,GAAG;AAC1B;AAAA,MACF;AACA,YAAM,UAAU,KAAK;AACrB,WAAK,gBAAgB,CAAC;AACtB,iBAAW,WAAW,SAAS;AAC7B,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,2BAA0C;AACxC,QAAI,KAAK,gBAAgB,GAAG;AAC1B,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,WAAK,cAAc,KAAK,OAAO;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,MAAM,+BAAkC,QAAqB,IAAkC;AAC7F,SAAK,uBAAuB,KAAK,MAAM;AACvC,QAAI;AACF,UAAI,CAAC,yBAAyB;AAC5B,eAAO,MAAM,GAAG;AAAA,MAClB;AACA,aAAO,MAAM,wBAAwB,IAAI,QAAQ,EAAE;AAAA,IACrD,UAAE;AACA,YAAM,MAAM,KAAK,uBAAuB,QAAQ,MAAM;AACtD,UAAI,OAAO,GAAG;AACZ,aAAK,uBAAuB,OAAO,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gDAAyE;AACvE,UAAM,SAAS,yBAAyB,SAAS;AACjD,WAAO,QAAQ,WAAW,YAAY,SAAS;AAAA,EACjD;AAAA,EAEA,2BAA0C;AACxC,WAAO,CAAC,GAAG,KAAK,sBAAsB;AAAA,EACxC;AAAA;AAAA,EAGA,sBAA+B;AAC7B,WAAO,KAAK,uBAAuB,SAAS;AAAA,EAC9C;AAAA,EAEA,YAAY,kBAAiC,MAAwB;AACnE,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,OAAO;AACX,UAAI,aAAmD;AAEvD,YAAM,SAAS,CAAC,gBAA+B;AAC7C,YAAI,MAAM;AACR;AAAA,QACF;AACA,eAAO;AACP,YAAI,eAAe,MAAM;AACvB,uBAAa,UAAU;AACvB,uBAAa;AAAA,QACf;AACA,gBAAQ,WAAW;AAAA,MACrB;AAEA,WAAK,aAAa,KAAK,MAAM;AAC7B,WAAK,kBAAkB;AAEvB,UAAI,oBAAoB,QAAQ,oBAAoB,QAAW;AAC7D;AAAA,MACF;AAEA,YAAM,aAAa,KAAK,IAAI,GAAG,OAAO,eAAe,CAAC,IAAI;AAC1D,UAAI,CAAC,OAAO,SAAS,UAAU,GAAG;AAChC;AAAA,MACF;AAEA,mBAAa,WAAW,MAAM;AAC5B,cAAM,QAAQ,KAAK,aAAa,QAAQ,MAAM;AAC9C,YAAI,SAAS,GAAG;AACd,eAAK,aAAa,OAAO,OAAO,CAAC;AAAA,QACnC;AACA,eAAO,KAAK;AAAA,MACd,GAAG,UAAU;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,uBAA6B;AAG3B,QAAI,KAAK,aAAa,WAAW,GAAG;AAClC,WAAK,oBAAoB;AACzB;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,IAAI,oBAAoB,GAAG;AACnC,WAAK,oBAAoB;AACzB,UAAI,KAAK,aAAa,SAAS,GAAG;AAChC,aAAK,kBAAkB;AAAA,MACzB;AACA;AAAA,IACF;AAEA,SAAK,qBAAqB;AAC1B,QAAI,KAAK,oBAAoB,GAAG;AAC9B,UAAI,KAAK,aAAa,SAAS,GAAG;AAChC,aAAK,kBAAkB;AAAA,MACzB;AACA;AAAA,IACF;AAEA,SAAK,oBAAoB;AACzB,UAAM,UAAU,KAAK;AACrB,SAAK,eAAe,CAAC;AACrB,eAAW,WAAW,SAAS;AAC7B,cAAQ,IAAI;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB,OAAoC;AAClD,UAAM,WAAW,MAAM,qBAAqB,KAAK,IAAI;AACrD,QAAI,aAAa,YAAY;AAC3B,aAAO;AAAA,IACT;AACA,QAAI,aAAa,iBAAiB;AAChC,aAAO,KAAK,IAAI;AAAA,IAClB;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,kBACJ,OACA,IACA,UAAkF,CAAC,GACvE;AACZ,UAAM,eAAe,QAAQ,qBAAqB;AAClD,QAAI,QAAQ,sBAAsB,cAAc;AAC9C,aAAO,MAAM,GAAG;AAAA,IAClB;AACA,WAAO,MAAM,YAAY,KAAK,gBAAgB,KAAK,GAAG,EAAE;AAAA,EAC1D;AAAA,EAEA,MAAM,oBACJ,OACA,6BACA,IACY;AACZ,UAAM,OAAO,MAAM,gBAAgB,2BAA2B;AAC9D,QAAI,MAAM;AACR,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,UAAM,eAAe,OAAO,IAAI,YAAY,IAAI,IAAI;AACpD,QAAI;AACF,aAAO,MAAM,GAAG,YAAY;AAAA,IAC9B,UAAE;AACA,oBAAc,eAAe;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA,EAIQ,oBAA0B;AAChC,QAAI,CAAC,KAAK,2BAA2B;AACnC;AAAA,IACF;AACA,QAAI,KAAK,oBAAoB;AAC3B;AAAA,IACF;AACA,SAAK,qBAAqB;AAC1B,eAAW,MAAM;AACf,WAAK,qBAAqB;AAC1B,WAAK,qBAAqB;AAAA,IAC5B,GAAG,CAAC;AAAA,EACN;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,cAAc;AACnB,SAAK,gBAAgB,CAAC;AACtB,SAAK,yBAAyB,CAAC;AAC/B,SAAK,eAAe,CAAC;AACrB,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AAAA,EAC3B;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseEvent } from "./
|
|
2
|
-
import { EventBus } from "./
|
|
1
|
+
import { BaseEvent } from "./BaseEvent.js";
|
|
2
|
+
import { EventBus } from "./EventBus.js";
|
|
3
3
|
import { assertOptionalDependencyAvailable, importOptionalDependency, isNodeRuntime } from "./optional_deps.js";
|
|
4
4
|
const randomSuffix = () => Math.random().toString(36).slice(2, 10);
|
|
5
5
|
class NATSEventBridge {
|
|
@@ -85,4 +85,4 @@ class NATSEventBridge {
|
|
|
85
85
|
export {
|
|
86
86
|
NATSEventBridge
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=
|
|
88
|
+
//# sourceMappingURL=NATSEventBridge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/NATSEventBridge.ts"],
|
|
4
|
+
"sourcesContent": ["import { BaseEvent } from './BaseEvent.js'\nimport { EventBus } from './EventBus.js'\nimport { assertOptionalDependencyAvailable, importOptionalDependency, isNodeRuntime } from './optional_deps.js'\nimport type { EventClass, EventHandlerCallable, EventPattern, UntypedEventHandlerFunction } from './types.js'\n\nconst randomSuffix = (): string => Math.random().toString(36).slice(2, 10)\n\nexport class NATSEventBridge {\n readonly server: string\n readonly subject: string\n readonly name: string\n\n private readonly inbound_bus: EventBus\n private running: boolean\n private nc: any | null\n private sub_task: Promise<void> | null\n\n constructor(server: string, subject: string, name?: string) {\n assertOptionalDependencyAvailable('NATSEventBridge', 'nats')\n\n this.server = server\n this.subject = subject\n this.name = name ?? `NATSEventBridge_${randomSuffix()}`\n this.inbound_bus = new EventBus(this.name, { max_history_size: 0 })\n this.running = false\n this.nc = null\n this.sub_task = null\n\n this.dispatch = this.dispatch.bind(this)\n this.emit = this.emit.bind(this)\n this.on = this.on.bind(this)\n }\n\n on<T extends BaseEvent>(event_pattern: EventClass<T>, handler: EventHandlerCallable<T>): void\n on<T extends BaseEvent>(event_pattern: string | '*', handler: UntypedEventHandlerFunction<T>): void\n on(event_pattern: EventPattern | '*', handler: EventHandlerCallable | UntypedEventHandlerFunction): void {\n this.ensureStarted()\n if (typeof event_pattern === 'string') {\n this.inbound_bus.on(event_pattern, handler as UntypedEventHandlerFunction<BaseEvent>)\n return\n }\n this.inbound_bus.on(event_pattern as EventClass<BaseEvent>, handler as EventHandlerCallable<BaseEvent>)\n }\n\n async emit<T extends BaseEvent>(event: T): Promise<void> {\n this.ensureStarted()\n if (!this.nc) await this.start()\n\n const payload = JSON.stringify(event.toJSON())\n this.nc.publish(this.subject, new TextEncoder().encode(payload))\n }\n\n async dispatch<T extends BaseEvent>(event: T): Promise<void> {\n return this.emit(event)\n }\n\n async start(): Promise<void> {\n if (this.running) return\n if (!isNodeRuntime()) {\n throw new Error('NATSEventBridge is only supported in Node.js runtimes')\n }\n\n const mod = await importOptionalDependency('NATSEventBridge', 'nats')\n const connect = mod.connect\n this.nc = await connect({ servers: this.server })\n const sub = this.nc.subscribe(this.subject)\n\n this.running = true\n this.sub_task = (async () => {\n for await (const msg of sub) {\n try {\n const payload = JSON.parse(new TextDecoder().decode(msg.data))\n await this.dispatchInboundPayload(payload)\n } catch {\n // Ignore malformed payloads.\n }\n }\n })()\n }\n\n async close(): Promise<void> {\n this.running = false\n if (this.nc) {\n await this.nc.drain()\n await this.nc.close()\n this.nc = null\n }\n await Promise.allSettled(this.sub_task ? [this.sub_task] : [])\n this.sub_task = null\n this.inbound_bus.destroy()\n }\n\n private ensureStarted(): void {\n if (this.running) return\n void this.start().catch((error: unknown) => {\n console.error('[abxbus] NATSEventBridge failed to start', error)\n })\n }\n\n private async dispatchInboundPayload(payload: unknown): Promise<void> {\n const event = BaseEvent.fromJSON(payload).eventReset()\n this.inbound_bus.emit(event)\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,mCAAmC,0BAA0B,qBAAqB;AAG3F,MAAM,eAAe,MAAc,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE;AAElE,MAAM,gBAAgB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAgB,SAAiB,MAAe;AAC1D,sCAAkC,mBAAmB,MAAM;AAE3D,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,OAAO,QAAQ,mBAAmB,aAAa,CAAC;AACrD,SAAK,cAAc,IAAI,SAAS,KAAK,MAAM,EAAE,kBAAkB,EAAE,CAAC;AAClE,SAAK,UAAU;AACf,SAAK,KAAK;AACV,SAAK,WAAW;AAEhB,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AACvC,SAAK,OAAO,KAAK,KAAK,KAAK,IAAI;AAC/B,SAAK,KAAK,KAAK,GAAG,KAAK,IAAI;AAAA,EAC7B;AAAA,EAIA,GAAG,eAAmC,SAAmE;AACvG,SAAK,cAAc;AACnB,QAAI,OAAO,kBAAkB,UAAU;AACrC,WAAK,YAAY,GAAG,eAAe,OAAiD;AACpF;AAAA,IACF;AACA,SAAK,YAAY,GAAG,eAAwC,OAA0C;AAAA,EACxG;AAAA,EAEA,MAAM,KAA0B,OAAyB;AACvD,SAAK,cAAc;AACnB,QAAI,CAAC,KAAK,GAAI,OAAM,KAAK,MAAM;AAE/B,UAAM,UAAU,KAAK,UAAU,MAAM,OAAO,CAAC;AAC7C,SAAK,GAAG,QAAQ,KAAK,SAAS,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,SAA8B,OAAyB;AAC3D,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,QAAS;AAClB,QAAI,CAAC,cAAc,GAAG;AACpB,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAEA,UAAM,MAAM,MAAM,yBAAyB,mBAAmB,MAAM;AACpE,UAAM,UAAU,IAAI;AACpB,SAAK,KAAK,MAAM,QAAQ,EAAE,SAAS,KAAK,OAAO,CAAC;AAChD,UAAM,MAAM,KAAK,GAAG,UAAU,KAAK,OAAO;AAE1C,SAAK,UAAU;AACf,SAAK,YAAY,YAAY;AAC3B,uBAAiB,OAAO,KAAK;AAC3B,YAAI;AACF,gBAAM,UAAU,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,IAAI,IAAI,CAAC;AAC7D,gBAAM,KAAK,uBAAuB,OAAO;AAAA,QAC3C,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,GAAG;AAAA,EACL;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,UAAU;AACf,QAAI,KAAK,IAAI;AACX,YAAM,KAAK,GAAG,MAAM;AACpB,YAAM,KAAK,GAAG,MAAM;AACpB,WAAK,KAAK;AAAA,IACZ;AACA,UAAM,QAAQ,WAAW,KAAK,WAAW,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC;AAC7D,SAAK,WAAW;AAChB,SAAK,YAAY,QAAQ;AAAA,EAC3B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,QAAS;AAClB,SAAK,KAAK,MAAM,EAAE,MAAM,CAAC,UAAmB;AAC1C,cAAQ,MAAM,4CAA4C,KAAK;AAAA,IACjE,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,uBAAuB,SAAiC;AACpE,UAAM,QAAQ,UAAU,SAAS,OAAO,EAAE,WAAW;AACrD,SAAK,YAAY,KAAK,KAAK;AAAA,EAC7B;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "@opentelemetry/api";
|
|
7
7
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
8
8
|
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
9
|
-
import { BasicTracerProvider,
|
|
9
|
+
import { BasicTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
10
10
|
import { SpanImpl } from "@opentelemetry/sdk-trace-base/build/src/Span.js";
|
|
11
11
|
class OtelTracingMiddleware {
|
|
12
12
|
tracer;
|
|
@@ -55,7 +55,7 @@ class OtelTracingMiddleware {
|
|
|
55
55
|
return existing;
|
|
56
56
|
}
|
|
57
57
|
const parent_context = this.parentContextForEvent(event) ?? ROOT_CONTEXT;
|
|
58
|
-
const start_time =
|
|
58
|
+
const start_time = timeInputFromIso(event.event_started_at);
|
|
59
59
|
const span = this.tracer.startSpan(
|
|
60
60
|
eventSpanName(eventbus, event),
|
|
61
61
|
{
|
|
@@ -83,8 +83,8 @@ class OtelTracingMiddleware {
|
|
|
83
83
|
span.setAttributes(
|
|
84
84
|
event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)
|
|
85
85
|
);
|
|
86
|
-
const start_time =
|
|
87
|
-
const end_time = endTimeAfterStart(start_time,
|
|
86
|
+
const start_time = epochNsFromIso(event.event_started_at);
|
|
87
|
+
const end_time = endTimeAfterStart(start_time, epochNsFromIso(event.event_completed_at));
|
|
88
88
|
span.end(end_time);
|
|
89
89
|
this.event_spans.delete(event.event_id);
|
|
90
90
|
this.event_contexts.delete(event.event_id);
|
|
@@ -99,7 +99,7 @@ class OtelTracingMiddleware {
|
|
|
99
99
|
handlerSpanName(event, event_result),
|
|
100
100
|
{
|
|
101
101
|
attributes: handlerSpanAttributes(eventbus, event, event_result),
|
|
102
|
-
startTime:
|
|
102
|
+
startTime: timeInputFromIso(event_result.started_at)
|
|
103
103
|
},
|
|
104
104
|
parent_context
|
|
105
105
|
);
|
|
@@ -121,10 +121,8 @@ class OtelTracingMiddleware {
|
|
|
121
121
|
} else {
|
|
122
122
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
123
123
|
}
|
|
124
|
-
span.setAttributes(
|
|
125
|
-
|
|
126
|
-
);
|
|
127
|
-
span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)));
|
|
124
|
+
span.setAttributes(handlerSpanAttributes(eventbus, event, event_result));
|
|
125
|
+
span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(event_result.completed_at)));
|
|
128
126
|
this.handler_spans.delete(event_result.id);
|
|
129
127
|
this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id));
|
|
130
128
|
}
|
|
@@ -151,21 +149,21 @@ class OtelTracingMiddleware {
|
|
|
151
149
|
return;
|
|
152
150
|
}
|
|
153
151
|
visited_event_ids.add(original_event.event_id);
|
|
154
|
-
const start_time =
|
|
152
|
+
const start_time = epochNsFromIso(original_event.event_started_at);
|
|
155
153
|
const span_context = eventSpanContext(trace_id, original_event.event_id);
|
|
156
154
|
const span = this.span_factory({
|
|
157
155
|
name: eventSpanName(eventbus, original_event),
|
|
158
156
|
span_context,
|
|
159
157
|
parent_span_context,
|
|
160
158
|
attributes: original_event.event_parent_id ? eventSpanAttributes(eventbus, original_event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),
|
|
161
|
-
start_time
|
|
159
|
+
start_time: timeInputFromEpochNs(start_time)
|
|
162
160
|
});
|
|
163
161
|
if (original_event.event_errors.length > 0) {
|
|
164
162
|
recordSpanError(span, original_event.event_errors[0]);
|
|
165
163
|
} else {
|
|
166
164
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
167
165
|
}
|
|
168
|
-
span.end(endTimeAfterStart(start_time,
|
|
166
|
+
span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)));
|
|
169
167
|
for (const event_result of original_event.event_results.values()) {
|
|
170
168
|
const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context);
|
|
171
169
|
for (const child of event_result.event_children) {
|
|
@@ -174,21 +172,21 @@ class OtelTracingMiddleware {
|
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
exportHandlerSpanWithFactory(eventbus, event, event_result, trace_id, parent_span_context) {
|
|
177
|
-
const start_time =
|
|
175
|
+
const start_time = epochNsFromIso(event_result.started_at);
|
|
178
176
|
const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id);
|
|
179
177
|
const span = this.span_factory({
|
|
180
178
|
name: handlerSpanName(event, event_result),
|
|
181
179
|
span_context,
|
|
182
180
|
parent_span_context,
|
|
183
181
|
attributes: handlerSpanAttributes(eventbus, event, event_result),
|
|
184
|
-
start_time
|
|
182
|
+
start_time: timeInputFromEpochNs(start_time)
|
|
185
183
|
});
|
|
186
184
|
if (event_result.error !== void 0) {
|
|
187
185
|
recordSpanError(span, event_result.error);
|
|
188
186
|
} else {
|
|
189
187
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
190
188
|
}
|
|
191
|
-
span.end(endTimeAfterStart(start_time,
|
|
189
|
+
span.end(endTimeAfterStart(start_time, epochNsFromIso(event_result.completed_at)));
|
|
192
190
|
return span_context;
|
|
193
191
|
}
|
|
194
192
|
}
|
|
@@ -207,10 +205,13 @@ function createOtlpSpanProvider(options) {
|
|
|
207
205
|
"service.name": options.service_name ?? "abxbus"
|
|
208
206
|
}),
|
|
209
207
|
spanProcessors: [
|
|
210
|
-
new
|
|
208
|
+
new BatchSpanProcessor(
|
|
211
209
|
new OTLPTraceExporter({
|
|
212
210
|
url: normalizeOtlpTracesEndpoint(options.otlp_endpoint)
|
|
213
|
-
})
|
|
211
|
+
}),
|
|
212
|
+
{
|
|
213
|
+
scheduledDelayMillis: 100
|
|
214
|
+
}
|
|
214
215
|
)
|
|
215
216
|
]
|
|
216
217
|
});
|
|
@@ -324,18 +325,40 @@ function fnv1a64Hex(input) {
|
|
|
324
325
|
}
|
|
325
326
|
return hash.toString(16).padStart(16, "0");
|
|
326
327
|
}
|
|
327
|
-
|
|
328
|
+
const ISO_EPOCH_NS_REGEX = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
|
|
329
|
+
const NS_PER_SECOND = 1000000000n;
|
|
330
|
+
const NS_PER_MS = 1000000n;
|
|
331
|
+
function epochNsFromIso(value) {
|
|
328
332
|
if (value == null) {
|
|
329
333
|
return void 0;
|
|
330
334
|
}
|
|
331
|
-
const
|
|
332
|
-
|
|
335
|
+
const match = ISO_EPOCH_NS_REGEX.exec(value);
|
|
336
|
+
if (!match) {
|
|
337
|
+
return void 0;
|
|
338
|
+
}
|
|
339
|
+
const [, base, fraction = "", timezone] = match;
|
|
340
|
+
const base_ms = Date.parse(`${base}.000${timezone}`);
|
|
341
|
+
if (Number.isNaN(base_ms)) {
|
|
342
|
+
return void 0;
|
|
343
|
+
}
|
|
344
|
+
return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, "0"));
|
|
345
|
+
}
|
|
346
|
+
function timeInputFromIso(value) {
|
|
347
|
+
return timeInputFromEpochNs(epochNsFromIso(value));
|
|
348
|
+
}
|
|
349
|
+
function timeInputFromEpochNs(epoch_ns) {
|
|
350
|
+
if (epoch_ns === void 0) {
|
|
351
|
+
return void 0;
|
|
352
|
+
}
|
|
353
|
+
const seconds = epoch_ns / NS_PER_SECOND;
|
|
354
|
+
const nanos = epoch_ns % NS_PER_SECOND;
|
|
355
|
+
return [Number(seconds), Number(nanos)];
|
|
333
356
|
}
|
|
334
357
|
function endTimeAfterStart(start_time, end_time) {
|
|
335
|
-
if (
|
|
336
|
-
return end_time;
|
|
358
|
+
if (start_time === void 0 || end_time === void 0) {
|
|
359
|
+
return timeInputFromEpochNs(end_time);
|
|
337
360
|
}
|
|
338
|
-
return end_time
|
|
361
|
+
return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n);
|
|
339
362
|
}
|
|
340
363
|
function resolveAttributes(attributes, eventbus, event) {
|
|
341
364
|
return typeof attributes === "function" ? attributes(eventbus, event) : attributes ?? {};
|
|
@@ -365,4 +388,4 @@ function recordSpanError(span, error) {
|
|
|
365
388
|
export {
|
|
366
389
|
OtelTracingMiddleware
|
|
367
390
|
};
|
|
368
|
-
//# sourceMappingURL=
|
|
391
|
+
//# sourceMappingURL=OtelTracingMiddleware.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/OtelTracingMiddleware.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanKind,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type SpanContext,\n type TimeInput,\n type Tracer,\n} from '@opentelemetry/api'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'\n\nimport type { BaseEvent } from './BaseEvent.js'\nimport type { EventBus } from './EventBus.js'\nimport type { EventResult } from './EventResult.js'\nimport type { EventBusMiddleware } from './EventBusMiddleware.js'\nimport type { EventStatus } from './types.js'\n\ntype OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'> & Partial<Pick<typeof trace, 'setSpanContext'>>\n\nexport type OtelTracingSpanFactoryInput = {\n name: string\n span_context: SpanContext\n parent_span_context?: SpanContext\n attributes: SpanAttributes\n start_time?: TimeInput\n}\n\nexport type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span\n\ntype OtelTracingSpanProviderInternals = {\n _activeSpanProcessor?: SpanProcessor\n _config?: {\n resource?: unknown\n spanLimits?: SpanLimits\n }\n _resource?: unknown\n}\n\nexport type OtelTracingSpanProvider = object\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_provider?: OtelTracingSpanProvider\n span_factory?: OtelTracingSpanFactory\n otlp_endpoint?: string\n service_name?: string\n instrumentation_name?: string\n root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)\n}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\n private readonly span_factory?: OtelTracingSpanFactory\n private readonly span_provider?: OtelTracingSpanProvider\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\n private readonly event_spans = new Map<string, Span>()\n private readonly event_contexts = new Map<string, Context>()\n private readonly handler_spans = new Map<string, Span>()\n private readonly handler_contexts = new Map<string, Context>()\n\n constructor(options: OtelTracingMiddlewareOptions = {}) {\n this.trace_api = options.trace_api ?? trace\n this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')\n this.span_provider = options.span_provider ?? (options.otlp_endpoint ? createOtlpSpanProvider(options) : undefined)\n this.span_factory =\n options.span_factory ??\n (this.span_provider\n ? createProviderSpanFactory(this.trace_api, this.span_provider, options.instrumentation_name ?? 'abxbus')\n : undefined)\n this.root_span_attributes = options.root_span_attributes\n }\n\n onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startEventSpan(eventbus, event)\n return\n }\n\n if (status === 'completed') {\n this.completeEventSpan(eventbus, event)\n }\n }\n\n onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startHandlerSpan(eventbus, event, event_result)\n return\n }\n\n if (status === 'completed') {\n this.completeHandlerSpan(eventbus, event, event_result)\n }\n }\n\n private startEventSpan(eventbus: EventBus, event: BaseEvent): Span {\n const existing = this.event_spans.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const parent_context = this.parentContextForEvent(event) ?? ROOT_CONTEXT\n const start_time = timeInputFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n eventSpanName(eventbus, event),\n {\n attributes: event.event_parent_id\n ? eventStartedSpanAttributes(eventbus, event)\n : topLevelEventStartedSpanAttributes(this.root_span_attributes, eventbus, event),\n startTime: start_time,\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.event_spans.set(event.event_id, span)\n this.event_contexts.set(event.event_id, span_context)\n return span\n }\n\n private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {\n if (this.span_factory) {\n this.completeEventSpanWithFactory(eventbus, event)\n return\n }\n\n const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)\n )\n const start_time = epochNsFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, epochNsFromIso(event.event_completed_at))\n span.end(end_time)\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\n }\n\n private startHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): Span {\n const existing = this.handler_spans.get(event_result.id)\n if (existing) {\n return existing\n }\n\n const parent_context =\n this.event_contexts.get(event.event_id) ?? this.trace_api.setSpan(ROOT_CONTEXT, this.startEventSpan(eventbus, event))\n const span = this.tracer.startSpan(\n handlerSpanName(event, event_result),\n {\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n startTime: timeInputFromIso(event_result.started_at),\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.handler_spans.set(event_result.id, span)\n this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context)\n return span\n }\n\n private completeHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {\n if (this.span_factory) {\n return\n }\n\n const span = this.handler_spans.get(event_result.id)\n if (!span) {\n return\n }\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(handlerSpanAttributes(eventbus, event, event_result))\n span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(event_result.completed_at)))\n this.handler_spans.delete(event_result.id)\n this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))\n }\n\n private parentContextForEvent(event: BaseEvent): Context | undefined {\n if (event.event_parent_id && event.event_emitted_by_handler_id) {\n const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id))\n if (handler_context) {\n return handler_context\n }\n }\n\n return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined\n }\n\n private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {\n if (event.event_parent_id) {\n return\n }\n\n const top_level_event = event._event_original ?? event\n const trace_id = traceIdForRootEvent(top_level_event.event_id)\n this.exportEventTreeWithFactory(eventbus, top_level_event, trace_id, undefined, new Set<string>())\n }\n\n private exportEventTreeWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n trace_id: string,\n parent_span_context: SpanContext | undefined,\n visited_event_ids: Set<string>\n ): void {\n const original_event = event._event_original ?? event\n if (visited_event_ids.has(original_event.event_id)) {\n return\n }\n visited_event_ids.add(original_event.event_id)\n\n const start_time = epochNsFromIso(original_event.event_started_at)\n const span_context = eventSpanContext(trace_id, original_event.event_id)\n const span = this.span_factory!({\n name: eventSpanName(eventbus, original_event),\n span_context,\n parent_span_context,\n attributes: original_event.event_parent_id\n ? eventSpanAttributes(eventbus, original_event)\n : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),\n start_time: timeInputFromEpochNs(start_time),\n })\n if (original_event.event_errors.length > 0) {\n recordSpanError(span, original_event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)))\n\n for (const event_result of original_event.event_results.values()) {\n const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)\n for (const child of event_result.event_children) {\n this.exportEventTreeWithFactory(eventbus, child, trace_id, handler_context, visited_event_ids)\n }\n }\n }\n\n private exportHandlerSpanWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n event_result: EventResult,\n trace_id: string,\n parent_span_context: SpanContext\n ): SpanContext {\n const start_time = epochNsFromIso(event_result.started_at)\n const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)\n const span = this.span_factory!({\n name: handlerSpanName(event, event_result),\n span_context,\n parent_span_context,\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time: timeInputFromEpochNs(start_time),\n })\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, epochNsFromIso(event_result.completed_at)))\n return span_context\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanName(eventbus: EventBus, event: BaseEvent): string {\n return `${eventbus.name}.emit(${event.event_type})`\n}\n\nfunction handlerSpanName(event: BaseEvent, event_result: EventResult): string {\n return `${event_result.handler_name}(${event.event_type})`\n}\n\nfunction createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTracingSpanProvider {\n return new BasicTracerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.service_name ?? 'abxbus',\n }),\n spanProcessors: [\n new BatchSpanProcessor(\n new OTLPTraceExporter({\n url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),\n }),\n {\n scheduledDelayMillis: 100,\n }\n ),\n ],\n })\n}\n\nfunction createProviderSpanFactory(\n trace_api: OpenTelemetryTraceApi,\n provider: OtelTracingSpanProvider,\n instrumentation_name: string\n): OtelTracingSpanFactory {\n const provider_internals = provider as OtelTracingSpanProviderInternals\n return (input: OtelTracingSpanFactoryInput): Span => {\n const span_processor = provider_internals._activeSpanProcessor\n const span_limits = provider_internals._config?.spanLimits\n const resource = provider_internals._resource ?? provider_internals._config?.resource\n if (!span_processor || !span_limits || !resource) {\n throw new Error('OtelTracingMiddleware span_provider must be an OpenTelemetry SDK trace provider with active span internals')\n }\n\n const parent_context = input.parent_span_context\n ? (trace_api.setSpanContext ?? trace.setSpanContext)(ROOT_CONTEXT, input.parent_span_context)\n : ROOT_CONTEXT\n return new SpanImpl({\n resource,\n scope: { name: instrumentation_name },\n context: parent_context,\n spanContext: input.span_context,\n parentSpanContext: input.parent_span_context,\n name: input.name,\n kind: SpanKind.INTERNAL,\n attributes: input.attributes,\n startTime: input.start_time,\n spanProcessor: span_processor,\n spanLimits: span_limits,\n } as ConstructorParameters<typeof SpanImpl>[0])\n }\n}\n\nfunction normalizeOtlpTracesEndpoint(endpoint: string): string {\n const trimmed = endpoint.replace(/\\/+$/, '')\n return trimmed.endsWith('/v1/traces') ? trimmed : `${trimmed}/v1/traces`\n}\n\nfunction eventStartedSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_bus.name': eventbus.name,\n 'abxbus.event_id': event.event_id,\n 'abxbus.event_type': event.event_type,\n 'abxbus.event_version': event.event_version,\n 'abxbus.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event_parent_id': event.event_parent_id,\n 'abxbus.event_emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event_path': event.event_path.join(' '),\n })\n}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n 'abxbus.event_status': event.event_status,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_bus.name': eventbus.name,\n 'abxbus.event_id': event.event_id,\n 'abxbus.event_type': event.event_type,\n 'abxbus.handler_id': event_result.handler_id,\n 'abxbus.handler_name': event_result.handler_name,\n 'abxbus.handler_file_path': event_result.handler_file_path,\n 'abxbus.handler_event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result_id': event_result.id,\n 'abxbus.event_result_status': event_result.status,\n })\n}\n\nfunction topLevelEventStartedSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction topLevelEventSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction eventSpanContext(trace_id: string, event_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.event:${event_id}`),\n traceFlags: 1,\n }\n}\n\nfunction handlerSpanContext(trace_id: string, event_id: string, handler_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),\n traceFlags: 1,\n }\n}\n\nfunction traceIdForRootEvent(event_id: string): string {\n return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`\n}\n\nfunction deterministicSpanId(input: string): string {\n return fnv1a64Hex(input)\n}\n\nfunction fnv1a64Hex(input: string): string {\n let hash = 0xcbf29ce484222325n\n const prime = 0x100000001b3n\n const mask = 0xffffffffffffffffn\n for (let index = 0; index < input.length; index += 1) {\n hash ^= BigInt(input.charCodeAt(index))\n hash = (hash * prime) & mask\n }\n if (hash === 0n) {\n hash = 1n\n }\n return hash.toString(16).padStart(16, '0')\n}\n\nconst ISO_EPOCH_NS_REGEX = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(?:\\.(\\d{1,9}))?(Z|[+-]\\d{2}:\\d{2})$/\nconst NS_PER_SECOND = 1_000_000_000n\nconst NS_PER_MS = 1_000_000n\n\nfunction epochNsFromIso(value: string | null | undefined): bigint | undefined {\n if (value == null) {\n return undefined\n }\n const match = ISO_EPOCH_NS_REGEX.exec(value)\n if (!match) {\n return undefined\n }\n const [, base, fraction = '', timezone] = match\n const base_ms = Date.parse(`${base}.000${timezone}`)\n if (Number.isNaN(base_ms)) {\n return undefined\n }\n return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, '0'))\n}\n\nfunction timeInputFromIso(value: string | null | undefined): TimeInput | undefined {\n return timeInputFromEpochNs(epochNsFromIso(value))\n}\n\nfunction timeInputFromEpochNs(epoch_ns: bigint | undefined): TimeInput | undefined {\n if (epoch_ns === undefined) {\n return undefined\n }\n const seconds = epoch_ns / NS_PER_SECOND\n const nanos = epoch_ns % NS_PER_SECOND\n return [Number(seconds), Number(nanos)]\n}\n\nfunction endTimeAfterStart(start_time: bigint | undefined, end_time: bigint | undefined): TimeInput | undefined {\n if (start_time === undefined || end_time === undefined) {\n return timeInputFromEpochNs(end_time)\n }\n\n return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n)\n}\n\nfunction resolveAttributes(\n attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return typeof attributes === 'function' ? attributes(eventbus, event) : (attributes ?? {})\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction compactAttributes(attributes: Record<string, SpanAttributeValue | null | undefined>): SpanAttributes {\n const compacted: SpanAttributes = {}\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== null && value !== undefined) {\n compacted[key] = value\n }\n }\n return compacted\n}\n\nfunction recordSpanError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n return\n }\n\n const message = typeof error === 'string' ? error : 'Unknown abxbus handler error'\n span.recordException(message)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseEvent } from "./
|
|
2
|
-
import { EventBus } from "./
|
|
1
|
+
import { BaseEvent } from "./BaseEvent.js";
|
|
2
|
+
import { EventBus } from "./EventBus.js";
|
|
3
3
|
import { assertOptionalDependencyAvailable, importOptionalDependency, isNodeRuntime } from "./optional_deps.js";
|
|
4
4
|
const randomSuffix = () => Math.random().toString(36).slice(2, 10);
|
|
5
5
|
const IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -228,4 +228,4 @@ class PostgresEventBridge {
|
|
|
228
228
|
export {
|
|
229
229
|
PostgresEventBridge
|
|
230
230
|
};
|
|
231
|
-
//# sourceMappingURL=
|
|
231
|
+
//# sourceMappingURL=PostgresEventBridge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/PostgresEventBridge.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * PostgreSQL LISTEN/NOTIFY + flat-table bridge for forwarding events.\n */\nimport { BaseEvent } from './BaseEvent.js'\nimport { EventBus } from './EventBus.js'\nimport { assertOptionalDependencyAvailable, importOptionalDependency, isNodeRuntime } from './optional_deps.js'\nimport type { EventClass, EventHandlerCallable, EventPattern, UntypedEventHandlerFunction } from './types.js'\n\nconst randomSuffix = (): string => Math.random().toString(36).slice(2, 10)\nconst IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_]*$/\nconst DEFAULT_POSTGRES_TABLE = 'abxbus_events'\nconst DEFAULT_POSTGRES_CHANNEL = 'abxbus_events'\nconst EVENT_PAYLOAD_COLUMN = 'event_payload'\n\nconst validateIdentifier = (value: string, label: string): string => {\n if (!IDENTIFIER_RE.test(value)) {\n throw new Error(`Invalid ${label}: ${JSON.stringify(value)}. Use only [A-Za-z0-9_] and start with a letter/_`)\n }\n return value\n}\n\nconst indexName = (table: string, suffix: string): string => validateIdentifier(`${table}_${suffix}`.slice(0, 63), 'index name')\n\nconst parseTableUrl = (table_url: string): { dsn: string; table: string } => {\n let parsed: URL\n try {\n parsed = new URL(table_url)\n } catch {\n throw new Error(\n 'PostgresEventBridge URL must include at least database in path, e.g. postgresql://user:pass@host:5432/dbname[/tablename]'\n )\n }\n\n const segments = parsed.pathname.split('/').filter(Boolean)\n if (segments.length < 1) {\n throw new Error(\n 'PostgresEventBridge URL must include at least database in path, e.g. postgresql://user:pass@host:5432/dbname[/tablename]'\n )\n }\n\n const db_name = segments[0]\n const table = segments.length >= 2 ? validateIdentifier(segments[1], 'table name') : DEFAULT_POSTGRES_TABLE\n const dsn_url = new URL(parsed.toString())\n dsn_url.pathname = `/${db_name}`\n return { dsn: dsn_url.toString(), table }\n}\n\nconst splitBridgePayload = (\n payload: Record<string, unknown>\n): { event_fields: Record<string, unknown>; event_payload: Record<string, unknown> } => {\n const event_fields: Record<string, unknown> = {}\n const event_payload: Record<string, unknown> = { ...payload }\n for (const [key, value] of Object.entries(payload)) {\n if (key.startsWith('event_')) {\n event_fields[key] = value\n }\n }\n return { event_fields, event_payload }\n}\n\nexport class PostgresEventBridge {\n readonly table_url: string\n readonly dsn: string\n readonly table: string\n readonly channel: string\n readonly name: string\n\n private readonly inbound_bus: EventBus\n private running: boolean\n private client: any | null\n private table_columns: Set<string>\n private notification_handler: ((msg: { channel: string; payload?: string }) => void) | null\n\n constructor(table_url: string, channel?: string, name?: string) {\n assertOptionalDependencyAvailable('PostgresEventBridge', 'pg')\n\n const parsed = parseTableUrl(table_url)\n this.table_url = table_url\n this.dsn = parsed.dsn\n this.table = parsed.table\n\n const derived_channel = channel ?? DEFAULT_POSTGRES_CHANNEL\n this.channel = validateIdentifier(derived_channel.slice(0, 63), 'channel name')\n this.name = name ?? `PostgresEventBridge_${randomSuffix()}`\n\n this.inbound_bus = new EventBus(this.name, { max_history_size: 0 })\n this.running = false\n this.client = null\n this.table_columns = new Set(['event_id', 'event_created_at', 'event_type', EVENT_PAYLOAD_COLUMN])\n this.notification_handler = null\n\n this.dispatch = this.dispatch.bind(this)\n this.emit = this.emit.bind(this)\n this.on = this.on.bind(this)\n }\n\n on<T extends BaseEvent>(event_pattern: EventClass<T>, handler: EventHandlerCallable<T>): void\n on<T extends BaseEvent>(event_pattern: string | '*', handler: UntypedEventHandlerFunction<T>): void\n on(event_pattern: EventPattern | '*', handler: EventHandlerCallable | UntypedEventHandlerFunction): void {\n this.ensureStarted()\n if (typeof event_pattern === 'string') {\n this.inbound_bus.on(event_pattern, handler as UntypedEventHandlerFunction<BaseEvent>)\n return\n }\n this.inbound_bus.on(event_pattern as EventClass<BaseEvent>, handler as EventHandlerCallable<BaseEvent>)\n }\n\n async emit<T extends BaseEvent>(event: T): Promise<void> {\n this.ensureStarted()\n if (!this.client) await this.start()\n\n const payload = event.toJSON() as Record<string, unknown>\n const { event_fields, event_payload } = splitBridgePayload(payload)\n const write_payload: Record<string, unknown> = { ...event_fields, [EVENT_PAYLOAD_COLUMN]: event_payload }\n const keys = Object.keys(write_payload).sort()\n await this.ensureColumns(keys)\n\n const columns_sql = keys.map((key) => `\"${key}\"`).join(', ')\n const placeholders_sql = keys.map((_, index) => `$${index + 1}`).join(', ')\n const values = keys.map((key) =>\n write_payload[key] === null || write_payload[key] === undefined ? null : JSON.stringify(write_payload[key])\n )\n\n const update_fields = keys.filter((key) => key !== 'event_id')\n let upsert_sql = `INSERT INTO \"${this.table}\" (${columns_sql}) VALUES (${placeholders_sql})`\n if (update_fields.length > 0) {\n const updates_sql = update_fields.map((key) => `\"${key}\" = EXCLUDED.\"${key}\"`).join(', ')\n upsert_sql += ` ON CONFLICT (\"event_id\") DO UPDATE SET ${updates_sql}`\n } else {\n upsert_sql += ' ON CONFLICT (\"event_id\") DO NOTHING'\n }\n\n await this.client.query(upsert_sql, values)\n await this.client.query('SELECT pg_notify($1, $2)', [this.channel, JSON.stringify(String(event.event_id))])\n }\n\n async dispatch<T extends BaseEvent>(event: T): Promise<void> {\n return this.emit(event)\n }\n\n async start(): Promise<void> {\n if (this.running) return\n if (!isNodeRuntime()) {\n throw new Error('PostgresEventBridge is only supported in Node.js runtimes')\n }\n\n const mod = await importOptionalDependency('PostgresEventBridge', 'pg')\n const Client = mod.Client ?? mod.default?.Client\n this.client = new Client({ connectionString: this.dsn })\n this.client.on('error', () => {})\n await this.client.connect()\n\n await this.ensureTableExists()\n await this.refreshColumnCache()\n await this.ensureColumns(['event_id', 'event_created_at', 'event_type', EVENT_PAYLOAD_COLUMN])\n await this.ensureBaseIndexes()\n\n this.notification_handler = (msg: { channel: string; payload?: string }) => {\n if (msg.channel !== this.channel || !msg.payload) return\n void this.dispatchByEventId(msg.payload).catch(() => {\n // Ignore transient shutdown races while closing connections.\n })\n }\n\n this.client.on('notification', this.notification_handler)\n await this.client.query(`LISTEN ${this.channel}`)\n this.running = true\n }\n\n async close(): Promise<void> {\n this.running = false\n if (this.client) {\n try {\n await this.client.query(`UNLISTEN ${this.channel}`)\n } catch {\n // ignore\n }\n if (this.notification_handler) {\n this.client.off('notification', this.notification_handler)\n this.notification_handler = null\n }\n await this.client.end()\n this.client = null\n }\n this.inbound_bus.destroy()\n }\n\n private ensureStarted(): void {\n if (this.running) return\n void this.start().catch((error: unknown) => {\n console.error('[abxbus] PostgresEventBridge failed to start', error)\n })\n }\n\n private async dispatchByEventId(event_id: string): Promise<void> {\n if (!this.running || !this.client) return\n const result = await this.client.query(`SELECT * FROM \"${this.table}\" WHERE \"event_id\" = $1`, [event_id])\n const row = result.rows?.[0] as Record<string, unknown> | undefined\n if (!row) return\n\n const payload: Record<string, unknown> = {}\n const raw_event_payload = row[EVENT_PAYLOAD_COLUMN]\n if (typeof raw_event_payload === 'string') {\n try {\n const decoded_event_payload = JSON.parse(raw_event_payload)\n if (decoded_event_payload && typeof decoded_event_payload === 'object' && !Array.isArray(decoded_event_payload)) {\n Object.assign(payload, decoded_event_payload as Record<string, unknown>)\n }\n } catch {\n // ignore malformed payload column\n }\n }\n\n for (const [key, raw_value] of Object.entries(row)) {\n if (key === EVENT_PAYLOAD_COLUMN || !key.startsWith('event_')) continue\n if (raw_value === null || raw_value === undefined) continue\n if (typeof raw_value !== 'string') {\n payload[key] = raw_value\n continue\n }\n try {\n payload[key] = JSON.parse(raw_value)\n } catch {\n payload[key] = raw_value\n }\n }\n\n await this.dispatchInboundPayload(payload)\n }\n\n private async dispatchInboundPayload(payload: unknown): Promise<void> {\n const event = BaseEvent.fromJSON(payload).eventReset()\n this.inbound_bus.emit(event)\n }\n\n private async ensureTableExists(): Promise<void> {\n if (!this.client) return\n await this.client.query(\n `CREATE TABLE IF NOT EXISTS \"${this.table}\" (\"event_id\" TEXT PRIMARY KEY, \"event_created_at\" TEXT, \"event_type\" TEXT, \"event_payload\" TEXT)`\n )\n }\n\n private async ensureBaseIndexes(): Promise<void> {\n if (!this.client) return\n\n const event_created_at_idx = indexName(this.table, 'event_created_at_idx')\n const event_type_idx = indexName(this.table, 'event_type_idx')\n\n await this.client.query(`CREATE INDEX IF NOT EXISTS \"${event_created_at_idx}\" ON \"${this.table}\" (\"event_created_at\")`)\n await this.client.query(`CREATE INDEX IF NOT EXISTS \"${event_type_idx}\" ON \"${this.table}\" (\"event_type\")`)\n }\n\n private async refreshColumnCache(): Promise<void> {\n if (!this.client) return\n const result = await this.client.query(\n `SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1`,\n [this.table]\n )\n this.table_columns = new Set((result.rows as Array<{ column_name: string }>).map((row) => row.column_name))\n }\n\n private async ensureColumns(keys: string[]): Promise<void> {\n if (!this.client) return\n for (const key of keys) {\n validateIdentifier(key, 'event field name')\n if (key !== EVENT_PAYLOAD_COLUMN && !key.startsWith('event_')) {\n throw new Error(`Invalid event field name for bridge column: ${JSON.stringify(key)}. Only event_* fields become columns`)\n }\n }\n\n const missing = keys.filter((key) => !this.table_columns.has(key))\n for (const key of missing) {\n await this.client.query(`ALTER TABLE \"${this.table}\" ADD COLUMN IF NOT EXISTS \"${key}\" TEXT`)\n this.table_columns.add(key)\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|