@burdenoff/be-sdk 2026.715.1 → 2026.716.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/EventQueueFactory-BDOT45WD.js +6 -0
  2. package/dist/{EventQueueFactory-AG6LQF77.js.map → EventQueueFactory-BDOT45WD.js.map} +1 -1
  3. package/dist/cache/index.d.ts +1 -1
  4. package/dist/cache/index.js +1 -1
  5. package/dist/{chunk-NKLJMTAT.js → chunk-5ORHPLOA.js} +3 -3
  6. package/dist/{chunk-NKLJMTAT.js.map → chunk-5ORHPLOA.js.map} +1 -1
  7. package/dist/{chunk-GVZ5BDER.js → chunk-A4TGVW5V.js} +3 -3
  8. package/dist/{chunk-GVZ5BDER.js.map → chunk-A4TGVW5V.js.map} +1 -1
  9. package/dist/{chunk-OIBCAEQJ.js → chunk-A6WNRJZF.js} +5 -5
  10. package/dist/{chunk-OIBCAEQJ.js.map → chunk-A6WNRJZF.js.map} +1 -1
  11. package/dist/{chunk-CAI5GJJ6.js → chunk-CJCO3OWF.js} +138 -14
  12. package/dist/chunk-CJCO3OWF.js.map +1 -0
  13. package/dist/{chunk-LHLOJS52.js → chunk-DBIWNA72.js} +2 -2
  14. package/dist/{chunk-LHLOJS52.js.map → chunk-DBIWNA72.js.map} +1 -1
  15. package/dist/{chunk-Y7X5AYKY.js → chunk-IMMJMVP7.js} +3 -3
  16. package/dist/{chunk-Y7X5AYKY.js.map → chunk-IMMJMVP7.js.map} +1 -1
  17. package/dist/{chunk-3XJUXXES.js → chunk-M5JYRRI6.js} +4 -4
  18. package/dist/{chunk-3XJUXXES.js.map → chunk-M5JYRRI6.js.map} +1 -1
  19. package/dist/{chunk-HDB3UKUN.js → chunk-OQ62HA7Z.js} +3 -3
  20. package/dist/{chunk-HDB3UKUN.js.map → chunk-OQ62HA7Z.js.map} +1 -1
  21. package/dist/{chunk-MHNA7IS7.js → chunk-S7LWYERE.js} +4 -2
  22. package/dist/chunk-S7LWYERE.js.map +1 -0
  23. package/dist/{chunk-X4NELQLV.js → chunk-UM32ZA3G.js} +3 -3
  24. package/dist/{chunk-X4NELQLV.js.map → chunk-UM32ZA3G.js.map} +1 -1
  25. package/dist/{chunk-GCY2FTHD.js → chunk-X5FPXATC.js} +3 -3
  26. package/dist/{chunk-GCY2FTHD.js.map → chunk-X5FPXATC.js.map} +1 -1
  27. package/dist/{chunk-3YZWPBKP.js → chunk-YKY24YLZ.js} +3 -3
  28. package/dist/{chunk-3YZWPBKP.js.map → chunk-YKY24YLZ.js.map} +1 -1
  29. package/dist/event-queue/index.js +4 -4
  30. package/dist/export/index.js +3 -3
  31. package/dist/gateway/index.js +2 -2
  32. package/dist/gateway/security/index.js +1 -1
  33. package/dist/graph/index.js +5 -5
  34. package/dist/graphql/index.js +2 -2
  35. package/dist/{index-Mr2ATGnY.d.ts → index-Zh4KQBM1.d.ts} +5 -0
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +15 -15
  38. package/dist/init/index.js +3 -3
  39. package/dist/prisma/index.js +4 -4
  40. package/package.json +1 -1
  41. package/dist/EventQueueFactory-AG6LQF77.js +0 -6
  42. package/dist/chunk-CAI5GJJ6.js.map +0 -1
  43. package/dist/chunk-MHNA7IS7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/event-queue/implementations/memory/MemoryEventQueue.ts","../src/event-queue/graph-emitter.ts"],"names":["MemoryEventBus","handlers","Map","emit","event","data","eventHandlers","get","forEach","handler","Promise","resolve","pattern","matchesPattern","on","has","set","Set","add","off","delete","endsWith","prefix","slice","startsWith","clear","MemoryEventQueue","queue","processing","maxRetries","retryDelay","options","publishEntityEvent","eventType","entity","context","subject","productName","type","split","logger","debug","entityId","id","entityType","enqueue","metadata","Date","now","randomUUID","timestamp","retries","push","processQueue","registerHandler","length","shift","ackEvent","correlationId","toISOString","ack","nak","term","isRedelivered","getDeliveryAttempt","setTimeout","publish","close","MemoryEventPublisher","_connected","publishCount","connect","info","disconnect","isConnected","ensureStream","Error","messageId","publishBatch","events","messageIds","publishWithAck","healthCheck","status","connected","latencyMs","getStatistics","messagesPublished","messagesConsumed","messagesPending","messagesFailed","getQueue","MemoryEventConsumer","bus","_subscriptions","consumeCount","subIdCounter","streamName","consumerName","stream","consumer","sub","values","unsubscribe","ensureConsumer","subscribe","subId","messagesReceived","messagesProcessed","lastActivity","active","subscription","isActive","getStats","subscriptionId","subscribeMultiple","subjects","subscriptions","pull","unsubscribeAll","getSubscriptions","Array","from","processDLQ","_handler","getBus","createMemoryPublisher","createMemoryConsumer","createGraphEventEmitter","uuidv4","crypto","GraphEventEmitterImpl","publisher","connecting","graphRedisUrl","process","env","EventQueueFactory","createPublisher","QueueType","REDIS_STREAMS","url","name","src","ensureConnected","then","rbac","eventId","action","hasRbac","streamSubjects","productSource","organizationId","actorId","workspaceId","result","isHealthy","healthy","message","error","_graphEventEmitter","getGraphEventEmitter","resetGraphEventEmitter"],"mappings":"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","file":"chunk-HDB3UKUN.js","sourcesContent":["/**\n * In-Memory Event Queue Implementation\n *\n * A simple in-memory event bus and queue for development/testing environments\n * or when NATS is not available. Implements the same interfaces as the NATS\n * implementation for seamless swapping.\n *\n * @module event-queue/memory\n * @category Events\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { logger } from '../../../logger/index.js';\nimport type { IEventPublisher, PublishOptions } from '../../interfaces/IEventPublisher.js';\nimport type { IEventConsumer, ISubscription } from '../../interfaces/IEventConsumer.js';\nimport type { EventHandler, AcknowledgeableEvent, EventMetadata } from '../../types/events.js';\nimport type { EventQueueHealthCheckResult, QueueStatistics } from '../../types/config.js';\n\n/**\n * Entity event type for graph events\n */\nexport type EntityEventType = 'entity.created' | 'entity.updated' | 'entity.deleted';\n\n/**\n * Graph event emitter interface - compatible with Prisma extension\n */\nexport interface GraphEventEmitter {\n publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n userId?: string;\n workspaceId?: string;\n }\n ): Promise<void>;\n}\n\n/**\n * Simple event bus for in-memory pub/sub\n */\nexport class MemoryEventBus {\n private handlers: Map<string, Set<EventHandler<unknown>>> = new Map();\n\n /**\n * Emit an event to all handlers\n */\n emit<T>(event: string, data: T): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n void Promise.resolve(handler(data as AcknowledgeableEvent));\n });\n }\n\n // Also emit to wildcard handlers\n for (const [pattern, handlers] of this.handlers) {\n if (this.matchesPattern(event, pattern)) {\n handlers.forEach((handler) => {\n void Promise.resolve(handler(data as AcknowledgeableEvent));\n });\n }\n }\n }\n\n /**\n * Register a handler for an event\n */\n on<T>(event: string, handler: EventHandler<T>): void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler as EventHandler<unknown>);\n }\n\n /**\n * Remove a handler for an event\n */\n off<T>(event: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n }\n }\n\n /**\n * Check if pattern matches event (supports wildcards)\n */\n private matchesPattern(event: string, pattern: string): boolean {\n if (pattern === event) return false; // Already handled exact match\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return event.startsWith(prefix + '.');\n }\n if (pattern.endsWith('.>')) {\n const prefix = pattern.slice(0, -2);\n return event.startsWith(prefix + '.');\n }\n return false;\n }\n\n /**\n * Clear all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/**\n * Queued event structure\n */\ninterface QueuedEvent<T = unknown> {\n id: string;\n subject: string;\n data: T;\n metadata: Record<string, unknown>;\n timestamp: Date;\n retries: number;\n maxRetries: number;\n}\n\n/**\n * In-memory event queue with retry support\n */\nexport class MemoryEventQueue implements GraphEventEmitter {\n private queue: QueuedEvent[] = [];\n private processing = false;\n private handlers: Map<string, EventHandler<unknown>> = new Map();\n private maxRetries: number;\n private retryDelay: number;\n\n constructor(options?: { maxRetries?: number; retryDelay?: number }) {\n this.maxRetries = options?.maxRetries ?? 3;\n this.retryDelay = options?.retryDelay ?? 1000;\n }\n\n /**\n * Publish entity event (implements GraphEventEmitter)\n */\n async publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n userId?: string;\n workspaceId?: string;\n }\n ): Promise<void> {\n const subject = `graph.${context.productName}.${entity.type}.${eventType.split('.')[1]}`;\n\n logger.debug('[MemoryEventQueue] Publishing entity event', {\n eventType,\n entityId: entity.id,\n entityType: entity.type,\n subject,\n });\n\n this.enqueue(subject, {\n eventType,\n entity,\n context,\n });\n }\n\n /**\n * Add an event to the queue\n */\n enqueue<T>(subject: string, data: T, metadata: Record<string, unknown> = {}): string {\n const id = `evt_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const event: QueuedEvent<T> = {\n id,\n subject,\n data,\n metadata,\n timestamp: new Date(),\n retries: 0,\n maxRetries: this.maxRetries,\n };\n this.queue.push(event);\n void this.processQueue();\n return id;\n }\n\n /**\n * Register a handler for a subject\n */\n registerHandler<T>(subject: string, handler: EventHandler<T>): void {\n this.handlers.set(subject, handler as EventHandler<unknown>);\n }\n\n /**\n * Process the queue\n */\n private async processQueue(): Promise<void> {\n if (this.processing || this.queue.length === 0) {\n return;\n }\n\n this.processing = true;\n\n while (this.queue.length > 0) {\n const event = this.queue.shift();\n if (!event) continue;\n\n const handler = this.handlers.get(event.subject);\n if (handler) {\n try {\n const ackEvent: AcknowledgeableEvent = {\n id: event.id,\n subject: event.subject,\n data: event.data,\n metadata: {\n correlationId: event.id,\n ...event.metadata,\n },\n timestamp: event.timestamp.toISOString(),\n ack: async () => {\n logger.debug('[MemoryEventQueue] Event acknowledged', { id: event.id });\n },\n nak: async () => {\n logger.debug('[MemoryEventQueue] Event negatively acknowledged', { id: event.id });\n if (event.retries < event.maxRetries) {\n event.retries++;\n this.queue.push(event);\n }\n },\n term: async () => {\n logger.debug('[MemoryEventQueue] Event terminated', { id: event.id });\n },\n isRedelivered: () => event.retries > 0,\n getDeliveryAttempt: () => event.retries + 1,\n };\n await handler(ackEvent);\n } catch {\n if (event.retries < event.maxRetries) {\n event.retries++;\n await new Promise((resolve) => setTimeout(resolve, this.retryDelay));\n this.queue.push(event);\n }\n }\n }\n }\n\n this.processing = false;\n }\n\n /**\n * Get queue length\n */\n get length(): number {\n return this.queue.length;\n }\n\n /**\n * Clear the queue\n */\n clear(): void {\n this.queue = [];\n }\n\n /**\n * Publish an event (fire-and-forget)\n */\n async publish<T>(subject: string, data: T, metadata: Record<string, unknown> = {}): Promise<void> {\n this.enqueue(subject, data, metadata);\n logger.debug('[MemoryEventQueue] Published event', { subject });\n }\n\n /**\n * Close the event queue\n */\n async close(): Promise<void> {\n this.clear();\n this.handlers.clear();\n logger.debug('[MemoryEventQueue] Event queue closed');\n }\n}\n\n/**\n * In-memory event publisher implementation\n */\nexport class MemoryEventPublisher implements IEventPublisher {\n private queue: MemoryEventQueue;\n private _connected = false;\n private publishCount = 0;\n\n constructor() {\n this.queue = new MemoryEventQueue();\n }\n\n async connect(): Promise<void> {\n this._connected = true;\n logger.info('[MemoryEventPublisher] Connected (in-memory mode)');\n }\n\n async disconnect(): Promise<void> {\n await this.queue.close();\n this._connected = false;\n logger.info('[MemoryEventPublisher] Disconnected');\n }\n\n isConnected(): boolean {\n return this._connected;\n }\n\n async ensureStream(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventPublisher] ensureStream called (no-op for in-memory)');\n }\n\n async publish<T = unknown>(options: {\n subject: string;\n data: T;\n metadata?: Record<string, unknown>;\n options?: PublishOptions;\n }): Promise<string> {\n if (!this._connected) {\n throw new Error('Publisher not connected');\n }\n\n const messageId = this.queue.enqueue(options.subject, options.data, options.metadata);\n this.publishCount++;\n\n logger.debug('[MemoryEventPublisher] Published', {\n subject: options.subject,\n messageId,\n });\n\n return messageId;\n }\n\n async publishBatch<T = unknown>(\n events: Array<{\n subject: string;\n data: T;\n metadata?: Record<string, unknown>;\n options?: PublishOptions;\n }>\n ): Promise<string[]> {\n const messageIds: string[] = [];\n for (const event of events) {\n const id = await this.publish(event);\n messageIds.push(id);\n }\n return messageIds;\n }\n\n async publishWithAck<T = unknown, R = unknown>(options: {\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n timeout?: number;\n }): Promise<R> {\n // For in-memory, just publish and return empty response\n await this.publish({\n subject: options.subject,\n data: options.data,\n metadata: options.metadata,\n });\n return {} as R;\n }\n\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n return {\n status: this._connected ? 'healthy' : 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: this._connected,\n latencyMs: 0,\n };\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return {\n messagesPublished: this.publishCount,\n messagesConsumed: 0,\n messagesPending: this.queue.length,\n messagesFailed: 0,\n };\n }\n\n /**\n * Get the underlying queue (for testing/debugging)\n */\n getQueue(): MemoryEventQueue {\n return this.queue;\n }\n}\n\n/**\n * In-memory event consumer implementation\n */\nexport class MemoryEventConsumer implements IEventConsumer {\n private queue: MemoryEventQueue;\n private bus: MemoryEventBus;\n private _connected = false;\n private _subscriptions: Map<string, ISubscription> = new Map();\n private consumeCount = 0;\n private subIdCounter = 0;\n\n constructor(\n private streamName: string,\n private consumerName: string\n ) {\n this.queue = new MemoryEventQueue();\n this.bus = new MemoryEventBus();\n }\n\n async connect(): Promise<void> {\n this._connected = true;\n logger.info('[MemoryEventConsumer] Connected (in-memory mode)', {\n stream: this.streamName,\n consumer: this.consumerName,\n });\n }\n\n async disconnect(): Promise<void> {\n for (const sub of this._subscriptions.values()) {\n await sub.unsubscribe();\n }\n this._subscriptions.clear();\n await this.queue.close();\n this.bus.clear();\n this._connected = false;\n logger.info('[MemoryEventConsumer] Disconnected');\n }\n\n isConnected(): boolean {\n return this._connected;\n }\n\n async ensureStream(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventConsumer] ensureStream called (no-op for in-memory)');\n }\n\n async ensureConsumer(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventConsumer] ensureConsumer called (no-op for in-memory)');\n }\n\n async subscribe<T = unknown>(options: {\n subject: string;\n handler: EventHandler<T>;\n queueGroup?: string;\n }): Promise<ISubscription> {\n if (!this._connected) {\n throw new Error('Consumer not connected');\n }\n\n const { subject, handler } = options;\n const subId = `sub_${++this.subIdCounter}`;\n let messagesReceived = 0;\n let messagesProcessed = 0;\n let messagesFailed = 0;\n let lastActivity = new Date().toISOString();\n let active = true;\n\n // Register with both queue and bus\n this.queue.registerHandler(subject, async (event) => {\n messagesReceived++;\n lastActivity = new Date().toISOString();\n try {\n this.consumeCount++;\n await handler(event as AcknowledgeableEvent<T>);\n messagesProcessed++;\n } catch {\n messagesFailed++;\n }\n });\n\n this.bus.on(subject, async (data) => {\n messagesReceived++;\n lastActivity = new Date().toISOString();\n try {\n this.consumeCount++;\n await handler(data as AcknowledgeableEvent<T>);\n messagesProcessed++;\n } catch {\n messagesFailed++;\n }\n });\n\n const subscription: ISubscription = {\n id: subId,\n subject,\n unsubscribe: async () => {\n active = false;\n this._subscriptions.delete(subId);\n logger.debug('[MemoryEventConsumer] Unsubscribed', { subject });\n },\n isActive: () => active,\n getStats: () => ({\n messagesReceived,\n messagesProcessed,\n messagesFailed,\n lastActivity,\n }),\n };\n\n this._subscriptions.set(subId, subscription);\n logger.info('[MemoryEventConsumer] Subscribed', { subject, subscriptionId: subId });\n\n return subscription;\n }\n\n async subscribeMultiple<T = unknown>(subjects: string[], handler: EventHandler<T>): Promise<ISubscription[]> {\n const subscriptions: ISubscription[] = [];\n for (const subject of subjects) {\n const sub = await this.subscribe<T>({ subject, handler });\n subscriptions.push(sub);\n }\n return subscriptions;\n }\n\n async pull<T = unknown>(): Promise<AcknowledgeableEvent<T>[]> {\n // In-memory doesn't support pull-based consumption in a meaningful way\n logger.debug('[MemoryEventConsumer] pull called (returning empty for in-memory)');\n return [];\n }\n\n async unsubscribeAll(): Promise<void> {\n for (const sub of this._subscriptions.values()) {\n await sub.unsubscribe();\n }\n this._subscriptions.clear();\n }\n\n getSubscriptions(): ISubscription[] {\n return Array.from(this._subscriptions.values());\n }\n\n async processDLQ<T = unknown>(_handler: EventHandler<T>): Promise<void> {\n // No-op for in-memory (no DLQ)\n logger.debug('[MemoryEventConsumer] processDLQ called (no-op for in-memory)');\n }\n\n // eslint-disable-next-line sonarjs/no-identical-functions -- Same implementation needed for both Publisher and Consumer\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n return {\n status: this._connected ? 'healthy' : 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: this._connected,\n latencyMs: 0,\n };\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return {\n messagesPublished: 0,\n messagesConsumed: this.consumeCount,\n messagesPending: this.queue.length,\n messagesFailed: 0,\n };\n }\n\n /**\n * Get the underlying bus (for testing/debugging)\n */\n getBus(): MemoryEventBus {\n return this.bus;\n }\n\n /**\n * Get the underlying queue (for testing/debugging)\n */\n getQueue(): MemoryEventQueue {\n return this.queue;\n }\n}\n\n/**\n * Create an in-memory event publisher\n */\nexport function createMemoryPublisher(): IEventPublisher {\n return new MemoryEventPublisher();\n}\n\n/**\n * Create an in-memory event consumer\n */\nexport function createMemoryConsumer(stream: string, consumer: string): IEventConsumer {\n return new MemoryEventConsumer(stream, consumer);\n}\n\n/**\n * Create a GraphEventEmitter instance (in-memory)\n */\nexport function createGraphEventEmitter(): GraphEventEmitter {\n return new MemoryEventQueue();\n}\n","/**\n * Graph Event Emitter\n *\n * Provides a GraphEventEmitter implementation that works with the event queue system.\n * Uses Redis Streams when REDIS_URL is set, in-memory otherwise.\n *\n * @module event-queue/graph-emitter\n * @category Events\n */\nimport { logger } from '../logger/index.js';\nimport { EventQueueFactory } from './factory/EventQueueFactory.js';\nimport { QueueType } from './types/config.js';\nimport type { IEventPublisher } from './interfaces/IEventPublisher.js';\nimport { MemoryEventPublisher } from './implementations/memory/MemoryEventQueue.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Entity event type for graph events\n */\nexport type EntityEventType = 'entity.created' | 'entity.updated' | 'entity.deleted';\n\n/**\n * RBAC metadata included in entity lifecycle events.\n * When present, the RBAC consumer will create/update/delete resources accordingly.\n * When absent, only the graph consumer processes the event (strict mode).\n */\nexport interface EntityEventRbacMetadata {\n /** RBAC resource type name (e.g., 'tag', 'conversation', 'bot') */\n resourceTypeName: string;\n /** Human-readable resource name */\n name?: string;\n /** Resource identifier (defaults to entity.id if not provided) */\n identifier?: string;\n /** Parent resource identifier for hierarchy */\n parentResourceIdentifier?: string;\n /** Whether to create a resource in RBAC (default: true) */\n createResource?: boolean;\n}\n\n/**\n * Graph event emitter interface - compatible with Prisma extension\n */\nexport interface GraphEventEmitter {\n publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n actorId?: string;\n workspaceId?: string;\n },\n rbac?: EntityEventRbacMetadata\n ): Promise<void>;\n}\n\n/**\n * Graph Event Emitter (Redis Streams-backed in production).\n *\n * Publishes graph entity events to the Redis Streams event bus for\n * processing by graph sync workers. Falls back to in-memory when\n * neither `GRAPH_REDIS_URL` nor `REDIS_URL` is set.\n *\n * `GRAPH_REDIS_URL` takes priority over `REDIS_URL` so that services\n * whose own cache Redis runs on a different db index (e.g. /14) can\n * still publish to the graph-svc's db index (e.g. /16) without\n * touching their primary Redis config.\n */\nexport class GraphEventEmitterImpl implements GraphEventEmitter {\n private publisher: IEventPublisher;\n private connected = false;\n private connecting: Promise<void> | null = null;\n\n constructor() {\n const graphRedisUrl = process.env['GRAPH_REDIS_URL'] ?? process.env['REDIS_URL'];\n if (graphRedisUrl) {\n this.publisher = EventQueueFactory.createPublisher({\n type: QueueType.REDIS_STREAMS,\n url: graphRedisUrl,\n name: process.env['QUEUE_CLIENT_NAME'] ?? process.env['SERVICE_NAME'] ?? 'graph-emitter',\n });\n const src = process.env['GRAPH_REDIS_URL'] ? 'GRAPH_REDIS_URL' : 'REDIS_URL';\n logger.info(`[GraphEventEmitter] Using Redis Streams publisher (${src})`);\n } else {\n this.publisher = new MemoryEventPublisher();\n logger.info('[GraphEventEmitter] Using in-memory publisher (GRAPH_REDIS_URL / REDIS_URL not configured)');\n }\n }\n\n /**\n * Ensure publisher is connected\n */\n private async ensureConnected(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n if (this.connecting) {\n await this.connecting;\n return;\n }\n\n this.connecting = this.publisher.connect().then(() => {\n this.connected = true;\n this.connecting = null;\n logger.info('[GraphEventEmitterImpl] Publisher connected');\n });\n\n await this.connecting;\n }\n\n /**\n * Publish entity event to graph queue\n *\n * @param eventType - The lifecycle event type\n * @param entity - Entity data (id, type, data)\n * @param context - Event context (product, org, user, workspace)\n * @param rbac - Optional RBAC metadata. When present, the RBAC consumer will\n * create/update/delete resources. When absent, only graph consumer processes.\n */\n async publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n actorId?: string;\n workspaceId?: string;\n },\n rbac?: EntityEventRbacMetadata\n ): Promise<void> {\n await this.ensureConnected();\n\n const eventId = uuidv4();\n const action = eventType.split('.')[1]; // 'created', 'updated', 'deleted'\n const subject = `graph.${context.productName}.${entity.type}.${action}`;\n\n logger.debug('[GraphEventEmitterImpl] Publishing entity event', {\n eventId,\n eventType,\n entityId: entity.id,\n entityType: entity.type,\n subject,\n hasRbac: !!rbac,\n });\n\n const streamName = process.env['GRAPH_SYNC_STREAM_NAME'] ?? 'WSPACE_GRAPH_EVENTS';\n const streamSubjects = ['graph.>'];\n\n await this.publisher.publish({\n subject,\n data: {\n eventId,\n eventType,\n productSource: context.productName,\n organizationId: context.organizationId,\n entity,\n context: {\n actorId: context.actorId,\n workspaceId: context.workspaceId,\n },\n // Include RBAC metadata when configured (consumed by rbac-entity-consumer)\n ...(rbac && { rbac }),\n timestamp: new Date().toISOString(),\n },\n metadata: {\n eventId,\n productName: context.productName,\n organizationId: context.organizationId,\n actorId: context.actorId,\n workspaceId: context.workspaceId,\n entityType: entity.type,\n entityId: entity.id,\n },\n options: {\n stream: streamName,\n streamSubjects,\n },\n });\n }\n\n /**\n * Disconnect the publisher\n */\n async disconnect(): Promise<void> {\n if (this.connected) {\n await this.publisher.disconnect();\n this.connected = false;\n logger.info('[GraphEventEmitterImpl] Publisher disconnected');\n }\n }\n\n /**\n * Get health check status\n */\n async healthCheck(): Promise<{ healthy: boolean; message: string }> {\n const result = await this.publisher.healthCheck();\n const isHealthy = result.status === 'healthy';\n return {\n healthy: isHealthy,\n message: result.error || (isHealthy ? 'Healthy' : 'Unhealthy'),\n };\n }\n}\n\n/**\n * Singleton instance\n */\nlet _graphEventEmitter: GraphEventEmitterImpl | null = null;\n\n/**\n * Get or create the graph event emitter singleton\n *\n * @returns Graph event emitter instance\n */\nexport function getGraphEventEmitter(): GraphEventEmitter {\n if (!_graphEventEmitter) {\n _graphEventEmitter = new GraphEventEmitterImpl();\n }\n return _graphEventEmitter;\n}\n\n/**\n * Create a new graph event emitter instance (non-singleton)\n *\n * @returns New graph event emitter instance\n */\nexport function createGraphEventEmitter(): GraphEventEmitter {\n return new GraphEventEmitterImpl();\n}\n\n/**\n * Reset the singleton (for testing)\n */\nexport async function resetGraphEventEmitter(): Promise<void> {\n if (_graphEventEmitter) {\n await _graphEventEmitter.disconnect();\n _graphEventEmitter = null;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/event-queue/implementations/memory/MemoryEventQueue.ts","../src/event-queue/graph-emitter.ts"],"names":["MemoryEventBus","handlers","Map","emit","event","data","eventHandlers","get","forEach","handler","Promise","resolve","pattern","matchesPattern","on","has","set","Set","add","off","delete","endsWith","prefix","slice","startsWith","clear","MemoryEventQueue","queue","processing","maxRetries","retryDelay","options","publishEntityEvent","eventType","entity","context","subject","productName","type","split","logger","debug","entityId","id","entityType","enqueue","metadata","Date","now","randomUUID","timestamp","retries","push","processQueue","registerHandler","length","shift","ackEvent","correlationId","toISOString","ack","nak","term","isRedelivered","getDeliveryAttempt","setTimeout","publish","close","MemoryEventPublisher","_connected","publishCount","connect","info","disconnect","isConnected","ensureStream","Error","messageId","publishBatch","events","messageIds","publishWithAck","healthCheck","status","connected","latencyMs","getStatistics","messagesPublished","messagesConsumed","messagesPending","messagesFailed","getQueue","MemoryEventConsumer","bus","_subscriptions","consumeCount","subIdCounter","streamName","consumerName","stream","consumer","sub","values","unsubscribe","ensureConsumer","subscribe","subId","messagesReceived","messagesProcessed","lastActivity","active","subscription","isActive","getStats","subscriptionId","subscribeMultiple","subjects","subscriptions","pull","unsubscribeAll","getSubscriptions","Array","from","processDLQ","_handler","getBus","createMemoryPublisher","createMemoryConsumer","createGraphEventEmitter","uuidv4","crypto","GraphEventEmitterImpl","publisher","connecting","graphRedisUrl","process","env","EventQueueFactory","createPublisher","QueueType","REDIS_STREAMS","url","name","src","ensureConnected","then","rbac","eventId","action","hasRbac","streamSubjects","productSource","organizationId","actorId","workspaceId","result","isHealthy","healthy","message","error","_graphEventEmitter","getGraphEventEmitter","resetGraphEventEmitter"],"mappings":"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","file":"chunk-OQ62HA7Z.js","sourcesContent":["/**\n * In-Memory Event Queue Implementation\n *\n * A simple in-memory event bus and queue for development/testing environments\n * or when NATS is not available. Implements the same interfaces as the NATS\n * implementation for seamless swapping.\n *\n * @module event-queue/memory\n * @category Events\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { logger } from '../../../logger/index.js';\nimport type { IEventPublisher, PublishOptions } from '../../interfaces/IEventPublisher.js';\nimport type { IEventConsumer, ISubscription } from '../../interfaces/IEventConsumer.js';\nimport type { EventHandler, AcknowledgeableEvent, EventMetadata } from '../../types/events.js';\nimport type { EventQueueHealthCheckResult, QueueStatistics } from '../../types/config.js';\n\n/**\n * Entity event type for graph events\n */\nexport type EntityEventType = 'entity.created' | 'entity.updated' | 'entity.deleted';\n\n/**\n * Graph event emitter interface - compatible with Prisma extension\n */\nexport interface GraphEventEmitter {\n publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n userId?: string;\n workspaceId?: string;\n }\n ): Promise<void>;\n}\n\n/**\n * Simple event bus for in-memory pub/sub\n */\nexport class MemoryEventBus {\n private handlers: Map<string, Set<EventHandler<unknown>>> = new Map();\n\n /**\n * Emit an event to all handlers\n */\n emit<T>(event: string, data: T): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n void Promise.resolve(handler(data as AcknowledgeableEvent));\n });\n }\n\n // Also emit to wildcard handlers\n for (const [pattern, handlers] of this.handlers) {\n if (this.matchesPattern(event, pattern)) {\n handlers.forEach((handler) => {\n void Promise.resolve(handler(data as AcknowledgeableEvent));\n });\n }\n }\n }\n\n /**\n * Register a handler for an event\n */\n on<T>(event: string, handler: EventHandler<T>): void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler as EventHandler<unknown>);\n }\n\n /**\n * Remove a handler for an event\n */\n off<T>(event: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n }\n }\n\n /**\n * Check if pattern matches event (supports wildcards)\n */\n private matchesPattern(event: string, pattern: string): boolean {\n if (pattern === event) return false; // Already handled exact match\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return event.startsWith(prefix + '.');\n }\n if (pattern.endsWith('.>')) {\n const prefix = pattern.slice(0, -2);\n return event.startsWith(prefix + '.');\n }\n return false;\n }\n\n /**\n * Clear all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/**\n * Queued event structure\n */\ninterface QueuedEvent<T = unknown> {\n id: string;\n subject: string;\n data: T;\n metadata: Record<string, unknown>;\n timestamp: Date;\n retries: number;\n maxRetries: number;\n}\n\n/**\n * In-memory event queue with retry support\n */\nexport class MemoryEventQueue implements GraphEventEmitter {\n private queue: QueuedEvent[] = [];\n private processing = false;\n private handlers: Map<string, EventHandler<unknown>> = new Map();\n private maxRetries: number;\n private retryDelay: number;\n\n constructor(options?: { maxRetries?: number; retryDelay?: number }) {\n this.maxRetries = options?.maxRetries ?? 3;\n this.retryDelay = options?.retryDelay ?? 1000;\n }\n\n /**\n * Publish entity event (implements GraphEventEmitter)\n */\n async publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n userId?: string;\n workspaceId?: string;\n }\n ): Promise<void> {\n const subject = `graph.${context.productName}.${entity.type}.${eventType.split('.')[1]}`;\n\n logger.debug('[MemoryEventQueue] Publishing entity event', {\n eventType,\n entityId: entity.id,\n entityType: entity.type,\n subject,\n });\n\n this.enqueue(subject, {\n eventType,\n entity,\n context,\n });\n }\n\n /**\n * Add an event to the queue\n */\n enqueue<T>(subject: string, data: T, metadata: Record<string, unknown> = {}): string {\n const id = `evt_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const event: QueuedEvent<T> = {\n id,\n subject,\n data,\n metadata,\n timestamp: new Date(),\n retries: 0,\n maxRetries: this.maxRetries,\n };\n this.queue.push(event);\n void this.processQueue();\n return id;\n }\n\n /**\n * Register a handler for a subject\n */\n registerHandler<T>(subject: string, handler: EventHandler<T>): void {\n this.handlers.set(subject, handler as EventHandler<unknown>);\n }\n\n /**\n * Process the queue\n */\n private async processQueue(): Promise<void> {\n if (this.processing || this.queue.length === 0) {\n return;\n }\n\n this.processing = true;\n\n while (this.queue.length > 0) {\n const event = this.queue.shift();\n if (!event) continue;\n\n const handler = this.handlers.get(event.subject);\n if (handler) {\n try {\n const ackEvent: AcknowledgeableEvent = {\n id: event.id,\n subject: event.subject,\n data: event.data,\n metadata: {\n correlationId: event.id,\n ...event.metadata,\n },\n timestamp: event.timestamp.toISOString(),\n ack: async () => {\n logger.debug('[MemoryEventQueue] Event acknowledged', { id: event.id });\n },\n nak: async () => {\n logger.debug('[MemoryEventQueue] Event negatively acknowledged', { id: event.id });\n if (event.retries < event.maxRetries) {\n event.retries++;\n this.queue.push(event);\n }\n },\n term: async () => {\n logger.debug('[MemoryEventQueue] Event terminated', { id: event.id });\n },\n isRedelivered: () => event.retries > 0,\n getDeliveryAttempt: () => event.retries + 1,\n };\n await handler(ackEvent);\n } catch {\n if (event.retries < event.maxRetries) {\n event.retries++;\n await new Promise((resolve) => setTimeout(resolve, this.retryDelay));\n this.queue.push(event);\n }\n }\n }\n }\n\n this.processing = false;\n }\n\n /**\n * Get queue length\n */\n get length(): number {\n return this.queue.length;\n }\n\n /**\n * Clear the queue\n */\n clear(): void {\n this.queue = [];\n }\n\n /**\n * Publish an event (fire-and-forget)\n */\n async publish<T>(subject: string, data: T, metadata: Record<string, unknown> = {}): Promise<void> {\n this.enqueue(subject, data, metadata);\n logger.debug('[MemoryEventQueue] Published event', { subject });\n }\n\n /**\n * Close the event queue\n */\n async close(): Promise<void> {\n this.clear();\n this.handlers.clear();\n logger.debug('[MemoryEventQueue] Event queue closed');\n }\n}\n\n/**\n * In-memory event publisher implementation\n */\nexport class MemoryEventPublisher implements IEventPublisher {\n private queue: MemoryEventQueue;\n private _connected = false;\n private publishCount = 0;\n\n constructor() {\n this.queue = new MemoryEventQueue();\n }\n\n async connect(): Promise<void> {\n this._connected = true;\n logger.info('[MemoryEventPublisher] Connected (in-memory mode)');\n }\n\n async disconnect(): Promise<void> {\n await this.queue.close();\n this._connected = false;\n logger.info('[MemoryEventPublisher] Disconnected');\n }\n\n isConnected(): boolean {\n return this._connected;\n }\n\n async ensureStream(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventPublisher] ensureStream called (no-op for in-memory)');\n }\n\n async publish<T = unknown>(options: {\n subject: string;\n data: T;\n metadata?: Record<string, unknown>;\n options?: PublishOptions;\n }): Promise<string> {\n if (!this._connected) {\n throw new Error('Publisher not connected');\n }\n\n const messageId = this.queue.enqueue(options.subject, options.data, options.metadata);\n this.publishCount++;\n\n logger.debug('[MemoryEventPublisher] Published', {\n subject: options.subject,\n messageId,\n });\n\n return messageId;\n }\n\n async publishBatch<T = unknown>(\n events: Array<{\n subject: string;\n data: T;\n metadata?: Record<string, unknown>;\n options?: PublishOptions;\n }>\n ): Promise<string[]> {\n const messageIds: string[] = [];\n for (const event of events) {\n const id = await this.publish(event);\n messageIds.push(id);\n }\n return messageIds;\n }\n\n async publishWithAck<T = unknown, R = unknown>(options: {\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n timeout?: number;\n }): Promise<R> {\n // For in-memory, just publish and return empty response\n await this.publish({\n subject: options.subject,\n data: options.data,\n metadata: options.metadata,\n });\n return {} as R;\n }\n\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n return {\n status: this._connected ? 'healthy' : 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: this._connected,\n latencyMs: 0,\n };\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return {\n messagesPublished: this.publishCount,\n messagesConsumed: 0,\n messagesPending: this.queue.length,\n messagesFailed: 0,\n };\n }\n\n /**\n * Get the underlying queue (for testing/debugging)\n */\n getQueue(): MemoryEventQueue {\n return this.queue;\n }\n}\n\n/**\n * In-memory event consumer implementation\n */\nexport class MemoryEventConsumer implements IEventConsumer {\n private queue: MemoryEventQueue;\n private bus: MemoryEventBus;\n private _connected = false;\n private _subscriptions: Map<string, ISubscription> = new Map();\n private consumeCount = 0;\n private subIdCounter = 0;\n\n constructor(\n private streamName: string,\n private consumerName: string\n ) {\n this.queue = new MemoryEventQueue();\n this.bus = new MemoryEventBus();\n }\n\n async connect(): Promise<void> {\n this._connected = true;\n logger.info('[MemoryEventConsumer] Connected (in-memory mode)', {\n stream: this.streamName,\n consumer: this.consumerName,\n });\n }\n\n async disconnect(): Promise<void> {\n for (const sub of this._subscriptions.values()) {\n await sub.unsubscribe();\n }\n this._subscriptions.clear();\n await this.queue.close();\n this.bus.clear();\n this._connected = false;\n logger.info('[MemoryEventConsumer] Disconnected');\n }\n\n isConnected(): boolean {\n return this._connected;\n }\n\n async ensureStream(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventConsumer] ensureStream called (no-op for in-memory)');\n }\n\n async ensureConsumer(): Promise<void> {\n // No-op for in-memory implementation\n logger.debug('[MemoryEventConsumer] ensureConsumer called (no-op for in-memory)');\n }\n\n async subscribe<T = unknown>(options: {\n subject: string;\n handler: EventHandler<T>;\n queueGroup?: string;\n }): Promise<ISubscription> {\n if (!this._connected) {\n throw new Error('Consumer not connected');\n }\n\n const { subject, handler } = options;\n const subId = `sub_${++this.subIdCounter}`;\n let messagesReceived = 0;\n let messagesProcessed = 0;\n let messagesFailed = 0;\n let lastActivity = new Date().toISOString();\n let active = true;\n\n // Register with both queue and bus\n this.queue.registerHandler(subject, async (event) => {\n messagesReceived++;\n lastActivity = new Date().toISOString();\n try {\n this.consumeCount++;\n await handler(event as AcknowledgeableEvent<T>);\n messagesProcessed++;\n } catch {\n messagesFailed++;\n }\n });\n\n this.bus.on(subject, async (data) => {\n messagesReceived++;\n lastActivity = new Date().toISOString();\n try {\n this.consumeCount++;\n await handler(data as AcknowledgeableEvent<T>);\n messagesProcessed++;\n } catch {\n messagesFailed++;\n }\n });\n\n const subscription: ISubscription = {\n id: subId,\n subject,\n unsubscribe: async () => {\n active = false;\n this._subscriptions.delete(subId);\n logger.debug('[MemoryEventConsumer] Unsubscribed', { subject });\n },\n isActive: () => active,\n getStats: () => ({\n messagesReceived,\n messagesProcessed,\n messagesFailed,\n lastActivity,\n }),\n };\n\n this._subscriptions.set(subId, subscription);\n logger.info('[MemoryEventConsumer] Subscribed', { subject, subscriptionId: subId });\n\n return subscription;\n }\n\n async subscribeMultiple<T = unknown>(subjects: string[], handler: EventHandler<T>): Promise<ISubscription[]> {\n const subscriptions: ISubscription[] = [];\n for (const subject of subjects) {\n const sub = await this.subscribe<T>({ subject, handler });\n subscriptions.push(sub);\n }\n return subscriptions;\n }\n\n async pull<T = unknown>(): Promise<AcknowledgeableEvent<T>[]> {\n // In-memory doesn't support pull-based consumption in a meaningful way\n logger.debug('[MemoryEventConsumer] pull called (returning empty for in-memory)');\n return [];\n }\n\n async unsubscribeAll(): Promise<void> {\n for (const sub of this._subscriptions.values()) {\n await sub.unsubscribe();\n }\n this._subscriptions.clear();\n }\n\n getSubscriptions(): ISubscription[] {\n return Array.from(this._subscriptions.values());\n }\n\n async processDLQ<T = unknown>(_handler: EventHandler<T>): Promise<void> {\n // No-op for in-memory (no DLQ)\n logger.debug('[MemoryEventConsumer] processDLQ called (no-op for in-memory)');\n }\n\n // eslint-disable-next-line sonarjs/no-identical-functions -- Same implementation needed for both Publisher and Consumer\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n return {\n status: this._connected ? 'healthy' : 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: this._connected,\n latencyMs: 0,\n };\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return {\n messagesPublished: 0,\n messagesConsumed: this.consumeCount,\n messagesPending: this.queue.length,\n messagesFailed: 0,\n };\n }\n\n /**\n * Get the underlying bus (for testing/debugging)\n */\n getBus(): MemoryEventBus {\n return this.bus;\n }\n\n /**\n * Get the underlying queue (for testing/debugging)\n */\n getQueue(): MemoryEventQueue {\n return this.queue;\n }\n}\n\n/**\n * Create an in-memory event publisher\n */\nexport function createMemoryPublisher(): IEventPublisher {\n return new MemoryEventPublisher();\n}\n\n/**\n * Create an in-memory event consumer\n */\nexport function createMemoryConsumer(stream: string, consumer: string): IEventConsumer {\n return new MemoryEventConsumer(stream, consumer);\n}\n\n/**\n * Create a GraphEventEmitter instance (in-memory)\n */\nexport function createGraphEventEmitter(): GraphEventEmitter {\n return new MemoryEventQueue();\n}\n","/**\n * Graph Event Emitter\n *\n * Provides a GraphEventEmitter implementation that works with the event queue system.\n * Uses Redis Streams when REDIS_URL is set, in-memory otherwise.\n *\n * @module event-queue/graph-emitter\n * @category Events\n */\nimport { logger } from '../logger/index.js';\nimport { EventQueueFactory } from './factory/EventQueueFactory.js';\nimport { QueueType } from './types/config.js';\nimport type { IEventPublisher } from './interfaces/IEventPublisher.js';\nimport { MemoryEventPublisher } from './implementations/memory/MemoryEventQueue.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Entity event type for graph events\n */\nexport type EntityEventType = 'entity.created' | 'entity.updated' | 'entity.deleted';\n\n/**\n * RBAC metadata included in entity lifecycle events.\n * When present, the RBAC consumer will create/update/delete resources accordingly.\n * When absent, only the graph consumer processes the event (strict mode).\n */\nexport interface EntityEventRbacMetadata {\n /** RBAC resource type name (e.g., 'tag', 'conversation', 'bot') */\n resourceTypeName: string;\n /** Human-readable resource name */\n name?: string;\n /** Resource identifier (defaults to entity.id if not provided) */\n identifier?: string;\n /** Parent resource identifier for hierarchy */\n parentResourceIdentifier?: string;\n /** Whether to create a resource in RBAC (default: true) */\n createResource?: boolean;\n}\n\n/**\n * Graph event emitter interface - compatible with Prisma extension\n */\nexport interface GraphEventEmitter {\n publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n actorId?: string;\n workspaceId?: string;\n },\n rbac?: EntityEventRbacMetadata\n ): Promise<void>;\n}\n\n/**\n * Graph Event Emitter (Redis Streams-backed in production).\n *\n * Publishes graph entity events to the Redis Streams event bus for\n * processing by graph sync workers. Falls back to in-memory when\n * neither `GRAPH_REDIS_URL` nor `REDIS_URL` is set.\n *\n * `GRAPH_REDIS_URL` takes priority over `REDIS_URL` so that services\n * whose own cache Redis runs on a different db index (e.g. /14) can\n * still publish to the graph-svc's db index (e.g. /16) without\n * touching their primary Redis config.\n */\nexport class GraphEventEmitterImpl implements GraphEventEmitter {\n private publisher: IEventPublisher;\n private connected = false;\n private connecting: Promise<void> | null = null;\n\n constructor() {\n const graphRedisUrl = process.env['GRAPH_REDIS_URL'] ?? process.env['REDIS_URL'];\n if (graphRedisUrl) {\n this.publisher = EventQueueFactory.createPublisher({\n type: QueueType.REDIS_STREAMS,\n url: graphRedisUrl,\n name: process.env['QUEUE_CLIENT_NAME'] ?? process.env['SERVICE_NAME'] ?? 'graph-emitter',\n });\n const src = process.env['GRAPH_REDIS_URL'] ? 'GRAPH_REDIS_URL' : 'REDIS_URL';\n logger.info(`[GraphEventEmitter] Using Redis Streams publisher (${src})`);\n } else {\n this.publisher = new MemoryEventPublisher();\n logger.info('[GraphEventEmitter] Using in-memory publisher (GRAPH_REDIS_URL / REDIS_URL not configured)');\n }\n }\n\n /**\n * Ensure publisher is connected\n */\n private async ensureConnected(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n if (this.connecting) {\n await this.connecting;\n return;\n }\n\n this.connecting = this.publisher.connect().then(() => {\n this.connected = true;\n this.connecting = null;\n logger.info('[GraphEventEmitterImpl] Publisher connected');\n });\n\n await this.connecting;\n }\n\n /**\n * Publish entity event to graph queue\n *\n * @param eventType - The lifecycle event type\n * @param entity - Entity data (id, type, data)\n * @param context - Event context (product, org, user, workspace)\n * @param rbac - Optional RBAC metadata. When present, the RBAC consumer will\n * create/update/delete resources. When absent, only graph consumer processes.\n */\n async publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n actorId?: string;\n workspaceId?: string;\n },\n rbac?: EntityEventRbacMetadata\n ): Promise<void> {\n await this.ensureConnected();\n\n const eventId = uuidv4();\n const action = eventType.split('.')[1]; // 'created', 'updated', 'deleted'\n const subject = `graph.${context.productName}.${entity.type}.${action}`;\n\n logger.debug('[GraphEventEmitterImpl] Publishing entity event', {\n eventId,\n eventType,\n entityId: entity.id,\n entityType: entity.type,\n subject,\n hasRbac: !!rbac,\n });\n\n const streamName = process.env['GRAPH_SYNC_STREAM_NAME'] ?? 'WSPACE_GRAPH_EVENTS';\n const streamSubjects = ['graph.>'];\n\n await this.publisher.publish({\n subject,\n data: {\n eventId,\n eventType,\n productSource: context.productName,\n organizationId: context.organizationId,\n entity,\n context: {\n actorId: context.actorId,\n workspaceId: context.workspaceId,\n },\n // Include RBAC metadata when configured (consumed by rbac-entity-consumer)\n ...(rbac && { rbac }),\n timestamp: new Date().toISOString(),\n },\n metadata: {\n eventId,\n productName: context.productName,\n organizationId: context.organizationId,\n actorId: context.actorId,\n workspaceId: context.workspaceId,\n entityType: entity.type,\n entityId: entity.id,\n },\n options: {\n stream: streamName,\n streamSubjects,\n },\n });\n }\n\n /**\n * Disconnect the publisher\n */\n async disconnect(): Promise<void> {\n if (this.connected) {\n await this.publisher.disconnect();\n this.connected = false;\n logger.info('[GraphEventEmitterImpl] Publisher disconnected');\n }\n }\n\n /**\n * Get health check status\n */\n async healthCheck(): Promise<{ healthy: boolean; message: string }> {\n const result = await this.publisher.healthCheck();\n const isHealthy = result.status === 'healthy';\n return {\n healthy: isHealthy,\n message: result.error || (isHealthy ? 'Healthy' : 'Unhealthy'),\n };\n }\n}\n\n/**\n * Singleton instance\n */\nlet _graphEventEmitter: GraphEventEmitterImpl | null = null;\n\n/**\n * Get or create the graph event emitter singleton\n *\n * @returns Graph event emitter instance\n */\nexport function getGraphEventEmitter(): GraphEventEmitter {\n if (!_graphEventEmitter) {\n _graphEventEmitter = new GraphEventEmitterImpl();\n }\n return _graphEventEmitter;\n}\n\n/**\n * Create a new graph event emitter instance (non-singleton)\n *\n * @returns New graph event emitter instance\n */\nexport function createGraphEventEmitter(): GraphEventEmitter {\n return new GraphEventEmitterImpl();\n}\n\n/**\n * Reset the singleton (for testing)\n */\nexport async function resetGraphEventEmitter(): Promise<void> {\n if (_graphEventEmitter) {\n await _graphEventEmitter.disconnect();\n _graphEventEmitter = null;\n }\n}\n"]}
@@ -175,6 +175,7 @@ var RedisStreamsConnection = class {
175
175
  }
176
176
  async doConnect() {
177
177
  const Redis = await loadIoRedis();
178
+ const keepAlive = parseInt(process.env["REDIS_STREAMS_KEEPALIVE"] ?? "30000", 10);
178
179
  const opts = {
179
180
  lazyConnect: true,
180
181
  maxRetriesPerRequest: null,
@@ -183,6 +184,7 @@ var RedisStreamsConnection = class {
183
184
  reconnectOnError: /* @__PURE__ */ __name(() => true, "reconnectOnError"),
184
185
  retryStrategy: /* @__PURE__ */ __name((times) => Math.min(times * 200, 2e3), "retryStrategy")
185
186
  };
187
+ if (Number.isFinite(keepAlive) && keepAlive > 0) opts["keepAlive"] = keepAlive;
186
188
  if (this.config.password) opts["password"] = this.config.password;
187
189
  if (this.config.user) opts["username"] = this.config.user;
188
190
  if (this.tls) {
@@ -243,5 +245,5 @@ var RedisStreamsConnection = class {
243
245
  };
244
246
 
245
247
  export { RedisStreamsConnection, boundaryOf, dedupKey, delayLockKey, delayQueueKey, dlqKey, isWildcard, matchSubject, registryKey, replyKey, streamKey };
246
- //# sourceMappingURL=chunk-MHNA7IS7.js.map
247
- //# sourceMappingURL=chunk-MHNA7IS7.js.map
248
+ //# sourceMappingURL=chunk-S7LWYERE.js.map
249
+ //# sourceMappingURL=chunk-S7LWYERE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/event-queue/implementations/redis-streams/keyspace.ts","../src/event-queue/implementations/redis-streams/RedisStreamsConnection.ts"],"names":["DEFAULT_PREFIX","REGISTRY_PREFIX","DELAYQ_PREFIX","DELAYQ_LOCK_PREFIX","DLQ_PREFIX","DEDUP_PREFIX","REPLY_PREFIX","currentScope","setKeyScope","scope","scoped","prefix","subjectToKey","subject","replace","streamKey","opts","registryKey","boundary","boundaryOf","first","split","delayQueueKey","stream","delayLockKey","dlqKey","dedupKey","msgId","replyKey","correlationId","matchSubject","pattern","pParts","sParts","last","length","i","isWildcard","includes","ioredisModulePromise","loadIoRedis","mod","default","Redis","err","logger","error","Error","message","String","ctor","normaliseUrl","rawUrl","url","tls","test","host","dbIndex","parsed","URL","hostname","pathDb","pathname","parseInt","toString","RedisStreamsConnection","client","connecting","normalisedUrl","config","process","env","isConnected","status","connect","doConnect","finally","keepAlive","lazyConnect","maxRetriesPerRequest","enableReadyCheck","connectTimeout","connectionTimeout","reconnectOnError","retryStrategy","times","Math","min","Number","isFinite","password","user","servername","on","args","warn","info","keyScope","disconnect","quit","getClient","makeBlockingClient","dup","duplicate","ping"],"mappings":"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","file":"chunk-S7LWYERE.js","sourcesContent":["/**\n * Redis Streams key namespace helpers.\n *\n * All keys are prefixed with `boff:` because DB 0 of Azure Managed Redis is\n * shared with the be-sdk cache provider.\n */\n\nexport interface KeyspaceOptions {\n /** Top-level prefix for event streams. Defaults to `boff:events`. */\n prefix?: string;\n}\n\nconst DEFAULT_PREFIX = 'boff:events';\nconst REGISTRY_PREFIX = 'boff:registry:subjects';\nconst DELAYQ_PREFIX = 'boff:delayq';\nconst DELAYQ_LOCK_PREFIX = 'boff:lock:delayq';\nconst DLQ_PREFIX = 'boff:dlq';\nconst DEDUP_PREFIX = 'boff:dedup';\nconst REPLY_PREFIX = 'boff:replies';\n\n// ── Process-wide key scope (DB-as-prefix) ────────────────────────────────\n//\n// Azure Managed Redis Balanced/B0 only exposes DB 0. Services that used to\n// rely on a non-zero DB index in their REDIS_URL (e.g. `…/4`) for namespace\n// isolation now share DB 0 — RedisStreamsConnection strips the path, pins\n// the connection to DB 0, and calls `setKeyScope(\"db4:\")` so every key that\n// flows through this module is automatically prefixed with `db4:`. That\n// preserves the per-service isolation the DB number used to give us without\n// any of the callers having to change.\n//\n// Default scope is empty (back-compat for services on classic Redis or\n// already using DB 0). Set once at connection time; reads are O(1).\nlet currentScope = '';\n\nexport function setKeyScope(scope: string): void {\n currentScope = scope ?? '';\n}\n\nexport function getKeyScope(): string {\n return currentScope;\n}\n\nfunction scoped(prefix: string): string {\n return currentScope ? `${currentScope}${prefix}` : prefix;\n}\n\n/** Convert a NATS-style subject to a Redis key segment (`.` → `:`). */\nexport function subjectToKey(subject: string): string {\n return subject.replace(/\\./g, ':');\n}\n\n/** Build the stream key for a given subject. */\nexport function streamKey(subject: string, opts: KeyspaceOptions = {}): string {\n const prefix = opts.prefix ?? DEFAULT_PREFIX;\n return `${scoped(prefix)}:${subjectToKey(subject)}`;\n}\n\n/** Stream key from a NATS-style wildcard prefix (e.g. `wspace`). */\nexport function registryKey(boundary: string): string {\n return `${scoped(REGISTRY_PREFIX)}:${boundary}`;\n}\n\n/** Extract the leading boundary (`x` in `x.y.z`). */\nexport function boundaryOf(subject: string): string {\n const first = subject.split('.')[0];\n return first ?? subject;\n}\n\n/** Sorted-set key for delayed-NAK re-delivery, scoped per stream. */\nexport function delayQueueKey(stream: string): string {\n return `${scoped(DELAYQ_PREFIX)}:${stream}`;\n}\n\n/** Lock key the delay-queue worker uses to serialise across replicas. */\nexport function delayLockKey(stream: string): string {\n return `${scoped(DELAYQ_LOCK_PREFIX)}:${stream}`;\n}\n\n/** Per-stream dead-letter queue. */\nexport function dlqKey(stream: string): string {\n return `${scoped(DLQ_PREFIX)}:${stream}`;\n}\n\n/** Per-message dedup marker key. */\nexport function dedupKey(stream: string, msgId: string): string {\n return `${scoped(DEDUP_PREFIX)}:${stream}:${msgId}`;\n}\n\n/** Reply-stream key for request/response emulation. */\nexport function replyKey(correlationId: string): string {\n return `${scoped(REPLY_PREFIX)}:${correlationId}`;\n}\n\n/**\n * Resolve a NATS-style subject pattern to a concrete list of stream keys, using\n * a registry of known subjects.\n *\n * Patterns supported:\n * - `x.y.z` — exact subject, returns single stream\n * - `x.>` — all subjects starting with `x.`\n * - `x.*` — all subjects with exactly one more segment after `x.`\n * - `x.*.z` — single-segment wildcard at position\n */\nexport function matchSubject(pattern: string, subject: string): boolean {\n if (pattern === subject) return true;\n const pParts = pattern.split('.');\n const sParts = subject.split('.');\n const last = pParts[pParts.length - 1];\n if (last === '>') {\n if (sParts.length < pParts.length) return false;\n for (let i = 0; i < pParts.length - 1; i++) {\n if (pParts[i] !== sParts[i]) return false;\n }\n return true;\n }\n if (pParts.length !== sParts.length) return false;\n for (let i = 0; i < pParts.length; i++) {\n if (pParts[i] !== '*' && pParts[i] !== sParts[i]) return false;\n }\n return true;\n}\n\n/** True if subject pattern contains a wildcard token. */\nexport function isWildcard(pattern: string): boolean {\n return pattern.includes('*') || pattern.includes('>');\n}\n","/**\n * Manages a single ioredis client (or cluster) for the Redis Streams backend.\n *\n * Connection URL conventions:\n * - `redis://host:port` — plaintext\n * - `rediss://host:port` — TLS (Azure Managed Redis uses port 10000)\n * - `valkey://`/`valkeys://` — accepted as aliases, normalised internally\n *\n * Hostname → SNI is set automatically for TLS endpoints so Azure-managed certs\n * validate.\n */\nimport { logger } from '../../../logger/index.js';\nimport type { BaseQueueConfig } from '../../types/config.js';\nimport { setKeyScope } from './keyspace.js';\n\ntype IoRedis = {\n status: string;\n connect: () => Promise<void>;\n disconnect: () => void;\n quit: () => Promise<unknown>;\n ping: () => Promise<string>;\n on: (event: string, handler: (...args: unknown[]) => void) => void;\n duplicate: () => IoRedis;\n // Stream + key commands used by publisher/consumer/sweeper\n xadd: (...args: unknown[]) => Promise<string>;\n xack: (...args: unknown[]) => Promise<number>;\n xreadgroup: (...args: unknown[]) => Promise<unknown>;\n xgroup: (...args: unknown[]) => Promise<unknown>;\n xautoclaim: (...args: unknown[]) => Promise<unknown>;\n xpending: (...args: unknown[]) => Promise<unknown>;\n xlen: (key: string) => Promise<number>;\n xinfo: (...args: unknown[]) => Promise<unknown>;\n xrevrange: (...args: unknown[]) => Promise<unknown>;\n xrange: (...args: unknown[]) => Promise<unknown>;\n xdel: (key: string, ...ids: string[]) => Promise<number>;\n set: (...args: unknown[]) => Promise<string | null>;\n expire: (key: string, seconds: number) => Promise<number>;\n del: (...keys: string[]) => Promise<number>;\n sadd: (key: string, ...members: string[]) => Promise<number>;\n smembers: (key: string) => Promise<string[]>;\n zadd: (...args: unknown[]) => Promise<number>;\n zrangebyscore: (...args: unknown[]) => Promise<string[]>;\n zrem: (key: string, ...members: string[]) => Promise<number>;\n pipeline: () => { xadd: (...args: unknown[]) => unknown; exec: () => Promise<Array<[Error | null, unknown]>> };\n};\n\ntype IoRedisCtor = new (url: string, opts: Record<string, unknown>) => IoRedis;\n\nlet ioredisModulePromise: Promise<IoRedisCtor | null> | null = null;\n\nasync function loadIoRedis(): Promise<IoRedisCtor> {\n if (!ioredisModulePromise) {\n ioredisModulePromise = (async () => {\n try {\n const mod = (await import('ioredis')) as unknown as { default?: IoRedisCtor; Redis?: IoRedisCtor };\n return mod.default ?? mod.Redis ?? null;\n } catch (err) {\n logger.error('[RedisStreamsConnection] ioredis not installed', {\n error: err instanceof Error ? err.message : String(err),\n });\n return null;\n }\n })();\n }\n const ctor = await ioredisModulePromise;\n if (!ctor) {\n throw new Error(\n '[RedisStreamsConnection] ioredis is required for the redis-streams event-queue backend. ' +\n 'Install it with: bun add ioredis (or npm i ioredis)'\n );\n }\n return ctor;\n}\n\nfunction normaliseUrl(rawUrl: string): { url: string; tls: boolean; host: string; dbIndex: number } {\n let url = rawUrl;\n let tls = false;\n if (/^valkeys:\\/\\//.test(url)) {\n tls = true;\n url = url.replace(/^valkeys:\\/\\//, 'rediss://');\n } else if (/^valkey:\\/\\//.test(url)) {\n url = url.replace(/^valkey:\\/\\//, 'redis://');\n } else if (/^rediss:\\/\\//.test(url)) {\n tls = true;\n }\n let host = 'localhost';\n let dbIndex = 0;\n try {\n const parsed = new URL(url);\n host = parsed.hostname || host;\n // Azure Managed Redis Balanced/B0 only exposes DB 0. If the URL pins a\n // non-zero DB in its path (e.g. `…/4`), ioredis would issue `SELECT 4`\n // on every reconnect and the server returns `ERR DB index is out of\n // range` in a tight loop that pegs the event loop. Strip the path here\n // so the connection lands on DB 0, then surface the original index to\n // the caller — we use it as a key-prefix scope so the per-service\n // isolation the DB number used to give us is preserved.\n const pathDb = parsed.pathname.replace(/^\\//, '');\n if (pathDb && /^\\d+$/.test(pathDb)) {\n dbIndex = parseInt(pathDb, 10);\n parsed.pathname = '';\n url = parsed.toString();\n }\n } catch {\n /* keep defaults */\n }\n return { url, tls, host, dbIndex };\n}\n\nexport class RedisStreamsConnection {\n private client: IoRedis | null = null;\n private connecting: Promise<void> | null = null;\n private readonly tls: boolean;\n private readonly host: string;\n private readonly normalisedUrl: string;\n private readonly dbIndex: number;\n\n constructor(private readonly config: BaseQueueConfig) {\n const { url, tls, host, dbIndex } = normaliseUrl(config.url);\n this.normalisedUrl = url;\n this.tls = tls || process.env['REDIS_TLS'] === 'true';\n this.host = host;\n this.dbIndex = dbIndex;\n // Install the DB-as-prefix scope before the first publish/consume runs.\n // Safe to call at construction: keyspace.setKeyScope is process-wide and\n // every key produced after this point will be prefixed with `db{N}:`.\n if (dbIndex > 0) {\n setKeyScope(`db${String(dbIndex)}:`);\n }\n }\n\n /** True once `connect()` has resolved and ioredis is in `ready` state. */\n isConnected(): boolean {\n return this.client !== null && this.client.status === 'ready';\n }\n\n /** Connect lazily; subsequent calls await the in-flight promise. */\n async connect(): Promise<void> {\n if (this.isConnected()) return;\n if (this.connecting) {\n await this.connecting;\n return;\n }\n this.connecting = this.doConnect().finally(() => {\n this.connecting = null;\n });\n await this.connecting;\n }\n\n private async doConnect(): Promise<void> {\n const Redis = await loadIoRedis();\n // Enable TCP keep-alive so half-open / stale sockets are detected and reclaimed\n // promptly instead of lingering server-side. Blocking XREAD connections (one per\n // subscribed stream) sit idle for long periods; without keep-alive, a connection\n // orphaned by a proxy failover, network drop, or Redis reprovision (e.g. a tier\n // scale) is not noticed until the next command, so stale sockets accumulate against\n // the server's connection cap during churn. 30s default; set REDIS_STREAMS_KEEPALIVE=0\n // to disable. ioredis passes this to socket.setKeepAlive(true, <ms>).\n const keepAlive = parseInt(process.env['REDIS_STREAMS_KEEPALIVE'] ?? '30000', 10);\n const opts: Record<string, unknown> = {\n lazyConnect: true,\n maxRetriesPerRequest: null,\n enableReadyCheck: true,\n connectTimeout: this.config.connectionTimeout ?? 15000,\n reconnectOnError: () => true,\n retryStrategy: (times: number): number => Math.min(times * 200, 2000),\n };\n if (Number.isFinite(keepAlive) && keepAlive > 0) opts['keepAlive'] = keepAlive;\n if (this.config.password) opts['password'] = this.config.password;\n if (this.config.user) opts['username'] = this.config.user;\n if (this.tls) {\n opts['tls'] = { servername: this.host };\n }\n this.client = new Redis(this.normalisedUrl, opts);\n this.client.on('error', (...args: unknown[]) => {\n const err = args[0] as Error | undefined;\n logger.warn('[RedisStreamsConnection] redis error', {\n error: err?.message ?? 'unknown',\n });\n });\n this.client.on('reconnecting', () => {\n logger.info('[RedisStreamsConnection] reconnecting');\n });\n await this.client.connect();\n logger.info('[RedisStreamsConnection] connected', {\n url: this.normalisedUrl.replace(/:[^:@/]*@/, ':***@'),\n tls: this.tls,\n dbIndex: this.dbIndex,\n keyScope: this.dbIndex > 0 ? `db${String(this.dbIndex)}:` : '',\n });\n }\n\n async disconnect(): Promise<void> {\n if (!this.client) return;\n try {\n await this.client.quit();\n } catch {\n this.client.disconnect();\n }\n this.client = null;\n }\n\n /** The shared command client. Throws if not connected. */\n getClient(): IoRedis {\n if (!this.client) {\n throw new Error('[RedisStreamsConnection] not connected — call connect() first');\n }\n return this.client;\n }\n\n /** Make a dedicated client (e.g. for a blocking XREADGROUP loop). */\n async makeBlockingClient(): Promise<IoRedis> {\n await this.connect();\n const dup = this.getClient().duplicate();\n if ('connect' in dup && typeof dup.connect === 'function') {\n try {\n await dup.connect();\n } catch {\n /* ioredis auto-connects in some versions */\n }\n }\n return dup;\n }\n\n async ping(): Promise<string> {\n await this.connect();\n return this.getClient().ping();\n }\n}\n\nexport type { IoRedis };\n"]}
@@ -1,5 +1,5 @@
1
1
  import { createDatabaseService, Logger } from './chunk-QLVKMWFA.js';
2
- import { RedisStreamsConnection } from './chunk-MHNA7IS7.js';
2
+ import { RedisStreamsConnection } from './chunk-S7LWYERE.js';
3
3
  import { logger } from './chunk-CBZNP6RF.js';
4
4
  import { __export, __name } from './chunk-XE4OXN2W.js';
5
5
 
@@ -177,5 +177,5 @@ async function createRedisStreamsEventTarget(options = {}) {
177
177
  __name(createRedisStreamsEventTarget, "createRedisStreamsEventTarget");
178
178
 
179
179
  export { createRedisStreamsEventTarget, graphql_exports };
180
- //# sourceMappingURL=chunk-X4NELQLV.js.map
181
- //# sourceMappingURL=chunk-X4NELQLV.js.map
180
+ //# sourceMappingURL=chunk-UM32ZA3G.js.map
181
+ //# sourceMappingURL=chunk-UM32ZA3G.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graphql/index.ts","../src/graphql/redis-streams-event-target.ts"],"names":["createRedisStreamsEventTarget","options","url","redisUrl","process","env","Error","prefix","subjectPrefix","maxLen","serializer","stringify","d","JSON","parse","m","conn","RedisStreamsConnection","type","password","name","connect","then","logger","info","catch","err","warn","error","message","String","streamKey","replace","listeners","Map","readers","closed","startReader","has","stopped","stream","loop","blockingClient","makeBlockingClient","lastId","raw","xreadgroup","call","debug","Promise","r","setTimeout","entries","id","rawFields","fields","i","length","payload","cbs","get","ev","CustomEvent","detail","cb","Array","from","cbErr","disconnect","set","stop","stopReader","delete","target","addEventListener","listener","Set","add","removeEventListener","size","dispatchEvent","event","getClient","xadd","close","values","clear","isHealthy","isConnected"],"mappings":"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","file":"chunk-X4NELQLV.js","sourcesContent":["/**\n * GraphQL Utilities Module\n *\n * Provides GraphQL-related utilities for Burdenoff products.\n *\n * @module graphql\n */\n\n// NATS event target was removed on 2026-05-16. Use\n// `createRedisStreamsEventTarget` from `./redis-streams-event-target.js`\n// for distributed GraphQL Yoga subscriptions.\n\nexport { createRedisStreamsEventTarget } from './redis-streams-event-target.js';\nexport type { RedisStreamsEventTarget, RedisStreamsEventTargetOptions } from './redis-streams-event-target.js';\n\n// Injectable services for GraphQL Modules\nexport { Logger, createDatabaseService } from './services/index.js';\nexport type { DatabaseService, PrismaTransactionClient } from './services/index.js';\n","/**\n * Redis Streams-based EventTarget for graphql-yoga distributed PubSub.\n *\n * Each server tails a per-event-type stream with `XREAD BLOCK ... $` (no\n * consumer group) so every instance receives every dispatch — the fan-out\n * semantics GraphQL subscriptions require.\n *\n * For durable inter-svc events use `event-queue/createPublisher` instead.\n */\nimport { logger } from '../logger/index.js';\nimport { RedisStreamsConnection } from '../event-queue/implementations/redis-streams/RedisStreamsConnection.js';\n\nexport interface RedisStreamsEventTarget {\n addEventListener(type: string, listener: (event: Event) => void): void;\n removeEventListener(type: string, listener: (event: Event) => void): void;\n dispatchEvent(event: Event): boolean;\n close(): Promise<void>;\n isHealthy(): boolean;\n}\n\nexport interface RedisStreamsEventTargetOptions {\n /** Redis connection URL. Defaults to `REDIS_URL` env. */\n redisUrl?: string;\n /** Optional password override. */\n password?: string;\n /** Subject prefix; keys become `<prefix>.<type>` mapped via `:` separator. */\n subjectPrefix?: string;\n /** Approximate MAXLEN trim for each pubsub stream. Default 1000. */\n maxLen?: number;\n /** Per-event serialiser. */\n serializer?: {\n stringify: (data: unknown) => string | Promise<string>;\n parse: (msg: string) => unknown | Promise<unknown>;\n };\n}\n\nexport async function createRedisStreamsEventTarget(\n options: RedisStreamsEventTargetOptions = {}\n): Promise<RedisStreamsEventTarget> {\n const url = options.redisUrl ?? process.env['REDIS_URL'];\n if (!url) throw new Error('[RedisStreamsEventTarget] redisUrl or REDIS_URL is required');\n const prefix = options.subjectPrefix ?? 'graphql.pubsub';\n const maxLen = options.maxLen ?? 1000;\n const serializer = options.serializer ?? {\n stringify: (d: unknown): string => JSON.stringify(d),\n parse: (m: string): unknown => JSON.parse(m),\n };\n\n const conn = new RedisStreamsConnection({\n type: 'redis-streams',\n url,\n password: options.password ?? process.env['REDIS_PASSWORD'],\n name: 'graphql-pubsub',\n });\n // Connect in the background — don't block svc startup on Redis reachability.\n void conn\n .connect()\n .then(() => logger.info('[RedisStreamsEventTarget] redis connected'))\n .catch((err) => {\n logger.warn('[RedisStreamsEventTarget] redis connect failed; pubsub will retry on demand', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n const streamKey = (type: string): string => `boff:pubsub:${prefix}:${type.replace(/\\./g, ':')}`;\n\n const listeners = new Map<string, Set<(event: Event) => void>>();\n const readers = new Map<string, { stop: () => void }>();\n let closed = false;\n\n function startReader(type: string): void {\n if (readers.has(type) || closed) return;\n let stopped = false;\n const stream = streamKey(type);\n\n const loop = async (): Promise<void> => {\n const blockingClient = await conn.makeBlockingClient();\n let lastId = '$';\n try {\n while (!stopped && !closed) {\n let raw: Array<[string, Array<[string, string[]]>]> | null = null;\n try {\n raw = (await blockingClient.xreadgroup(\n // pretend-arg pattern: we actually want XREAD, fall through\n 'COUNT',\n 50,\n 'BLOCK',\n 5000,\n 'STREAMS',\n stream,\n lastId\n )) as Array<[string, Array<[string, string[]]>]> | null;\n } catch {\n // Some ioredis typings make xreadgroup the only signature; fall back to xread via raw command.\n try {\n raw = (await (\n blockingClient as unknown as {\n call: (...args: unknown[]) => Promise<unknown>;\n }\n ).call('XREAD', 'COUNT', 50, 'BLOCK', 5000, 'STREAMS', stream, lastId)) as Array<\n [string, Array<[string, string[]]>]\n > | null;\n } catch (err) {\n logger.debug('[RedisStreamsEventTarget] xread error', {\n stream,\n error: err instanceof Error ? err.message : String(err),\n });\n await new Promise((r) => setTimeout(r, 1000));\n continue;\n }\n }\n if (!raw) continue;\n for (const [, entries] of raw) {\n for (const [id, rawFields] of entries) {\n lastId = id;\n const fields: Record<string, string> = {};\n for (let i = 0; i + 1 < rawFields.length; i += 2) {\n fields[rawFields[i]!] = rawFields[i + 1]!;\n }\n const payload = await serializer.parse(fields['payload'] ?? 'null');\n const cbs = listeners.get(type);\n if (!cbs) continue;\n const ev = new CustomEvent(type, { detail: payload });\n for (const cb of Array.from(cbs)) {\n try {\n cb(ev);\n } catch (cbErr) {\n logger.error('[RedisStreamsEventTarget] listener error', {\n type,\n error: cbErr instanceof Error ? cbErr.message : String(cbErr),\n });\n }\n }\n }\n }\n }\n } finally {\n try {\n blockingClient.disconnect();\n } catch {\n /* ignore */\n }\n }\n };\n\n readers.set(type, {\n stop: (): void => {\n stopped = true;\n },\n });\n void loop().catch((err) => {\n logger.error('[RedisStreamsEventTarget] reader crashed', {\n type,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n function stopReader(type: string): void {\n const r = readers.get(type);\n if (r) {\n r.stop();\n readers.delete(type);\n }\n }\n\n const target: RedisStreamsEventTarget = {\n addEventListener(type, listener): void {\n let set = listeners.get(type);\n if (!set) {\n set = new Set();\n listeners.set(type, set);\n startReader(type);\n }\n set.add(listener);\n },\n removeEventListener(type, listener): void {\n const set = listeners.get(type);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) {\n listeners.delete(type);\n stopReader(type);\n }\n },\n dispatchEvent(event): boolean {\n const detail = 'detail' in event ? (event as CustomEvent).detail : event;\n void (async (): Promise<void> => {\n try {\n const payload = await serializer.stringify(detail);\n await conn.getClient().xadd(streamKey(event.type), 'MAXLEN', '~', maxLen, '*', 'payload', payload);\n } catch (err) {\n logger.error('[RedisStreamsEventTarget] dispatch failed', {\n type: event.type,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n })();\n return true;\n },\n async close(): Promise<void> {\n closed = true;\n for (const r of readers.values()) r.stop();\n readers.clear();\n listeners.clear();\n await conn.disconnect();\n },\n isHealthy(): boolean {\n return conn.isConnected();\n },\n };\n\n logger.info('[RedisStreamsEventTarget] ready', { prefix });\n return target;\n}\n"]}
1
+ {"version":3,"sources":["../src/graphql/index.ts","../src/graphql/redis-streams-event-target.ts"],"names":["createRedisStreamsEventTarget","options","url","redisUrl","process","env","Error","prefix","subjectPrefix","maxLen","serializer","stringify","d","JSON","parse","m","conn","RedisStreamsConnection","type","password","name","connect","then","logger","info","catch","err","warn","error","message","String","streamKey","replace","listeners","Map","readers","closed","startReader","has","stopped","stream","loop","blockingClient","makeBlockingClient","lastId","raw","xreadgroup","call","debug","Promise","r","setTimeout","entries","id","rawFields","fields","i","length","payload","cbs","get","ev","CustomEvent","detail","cb","Array","from","cbErr","disconnect","set","stop","stopReader","delete","target","addEventListener","listener","Set","add","removeEventListener","size","dispatchEvent","event","getClient","xadd","close","values","clear","isHealthy","isConnected"],"mappings":"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","file":"chunk-UM32ZA3G.js","sourcesContent":["/**\n * GraphQL Utilities Module\n *\n * Provides GraphQL-related utilities for Burdenoff products.\n *\n * @module graphql\n */\n\n// NATS event target was removed on 2026-05-16. Use\n// `createRedisStreamsEventTarget` from `./redis-streams-event-target.js`\n// for distributed GraphQL Yoga subscriptions.\n\nexport { createRedisStreamsEventTarget } from './redis-streams-event-target.js';\nexport type { RedisStreamsEventTarget, RedisStreamsEventTargetOptions } from './redis-streams-event-target.js';\n\n// Injectable services for GraphQL Modules\nexport { Logger, createDatabaseService } from './services/index.js';\nexport type { DatabaseService, PrismaTransactionClient } from './services/index.js';\n","/**\n * Redis Streams-based EventTarget for graphql-yoga distributed PubSub.\n *\n * Each server tails a per-event-type stream with `XREAD BLOCK ... $` (no\n * consumer group) so every instance receives every dispatch — the fan-out\n * semantics GraphQL subscriptions require.\n *\n * For durable inter-svc events use `event-queue/createPublisher` instead.\n */\nimport { logger } from '../logger/index.js';\nimport { RedisStreamsConnection } from '../event-queue/implementations/redis-streams/RedisStreamsConnection.js';\n\nexport interface RedisStreamsEventTarget {\n addEventListener(type: string, listener: (event: Event) => void): void;\n removeEventListener(type: string, listener: (event: Event) => void): void;\n dispatchEvent(event: Event): boolean;\n close(): Promise<void>;\n isHealthy(): boolean;\n}\n\nexport interface RedisStreamsEventTargetOptions {\n /** Redis connection URL. Defaults to `REDIS_URL` env. */\n redisUrl?: string;\n /** Optional password override. */\n password?: string;\n /** Subject prefix; keys become `<prefix>.<type>` mapped via `:` separator. */\n subjectPrefix?: string;\n /** Approximate MAXLEN trim for each pubsub stream. Default 1000. */\n maxLen?: number;\n /** Per-event serialiser. */\n serializer?: {\n stringify: (data: unknown) => string | Promise<string>;\n parse: (msg: string) => unknown | Promise<unknown>;\n };\n}\n\nexport async function createRedisStreamsEventTarget(\n options: RedisStreamsEventTargetOptions = {}\n): Promise<RedisStreamsEventTarget> {\n const url = options.redisUrl ?? process.env['REDIS_URL'];\n if (!url) throw new Error('[RedisStreamsEventTarget] redisUrl or REDIS_URL is required');\n const prefix = options.subjectPrefix ?? 'graphql.pubsub';\n const maxLen = options.maxLen ?? 1000;\n const serializer = options.serializer ?? {\n stringify: (d: unknown): string => JSON.stringify(d),\n parse: (m: string): unknown => JSON.parse(m),\n };\n\n const conn = new RedisStreamsConnection({\n type: 'redis-streams',\n url,\n password: options.password ?? process.env['REDIS_PASSWORD'],\n name: 'graphql-pubsub',\n });\n // Connect in the background — don't block svc startup on Redis reachability.\n void conn\n .connect()\n .then(() => logger.info('[RedisStreamsEventTarget] redis connected'))\n .catch((err) => {\n logger.warn('[RedisStreamsEventTarget] redis connect failed; pubsub will retry on demand', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n const streamKey = (type: string): string => `boff:pubsub:${prefix}:${type.replace(/\\./g, ':')}`;\n\n const listeners = new Map<string, Set<(event: Event) => void>>();\n const readers = new Map<string, { stop: () => void }>();\n let closed = false;\n\n function startReader(type: string): void {\n if (readers.has(type) || closed) return;\n let stopped = false;\n const stream = streamKey(type);\n\n const loop = async (): Promise<void> => {\n const blockingClient = await conn.makeBlockingClient();\n let lastId = '$';\n try {\n while (!stopped && !closed) {\n let raw: Array<[string, Array<[string, string[]]>]> | null = null;\n try {\n raw = (await blockingClient.xreadgroup(\n // pretend-arg pattern: we actually want XREAD, fall through\n 'COUNT',\n 50,\n 'BLOCK',\n 5000,\n 'STREAMS',\n stream,\n lastId\n )) as Array<[string, Array<[string, string[]]>]> | null;\n } catch {\n // Some ioredis typings make xreadgroup the only signature; fall back to xread via raw command.\n try {\n raw = (await (\n blockingClient as unknown as {\n call: (...args: unknown[]) => Promise<unknown>;\n }\n ).call('XREAD', 'COUNT', 50, 'BLOCK', 5000, 'STREAMS', stream, lastId)) as Array<\n [string, Array<[string, string[]]>]\n > | null;\n } catch (err) {\n logger.debug('[RedisStreamsEventTarget] xread error', {\n stream,\n error: err instanceof Error ? err.message : String(err),\n });\n await new Promise((r) => setTimeout(r, 1000));\n continue;\n }\n }\n if (!raw) continue;\n for (const [, entries] of raw) {\n for (const [id, rawFields] of entries) {\n lastId = id;\n const fields: Record<string, string> = {};\n for (let i = 0; i + 1 < rawFields.length; i += 2) {\n fields[rawFields[i]!] = rawFields[i + 1]!;\n }\n const payload = await serializer.parse(fields['payload'] ?? 'null');\n const cbs = listeners.get(type);\n if (!cbs) continue;\n const ev = new CustomEvent(type, { detail: payload });\n for (const cb of Array.from(cbs)) {\n try {\n cb(ev);\n } catch (cbErr) {\n logger.error('[RedisStreamsEventTarget] listener error', {\n type,\n error: cbErr instanceof Error ? cbErr.message : String(cbErr),\n });\n }\n }\n }\n }\n }\n } finally {\n try {\n blockingClient.disconnect();\n } catch {\n /* ignore */\n }\n }\n };\n\n readers.set(type, {\n stop: (): void => {\n stopped = true;\n },\n });\n void loop().catch((err) => {\n logger.error('[RedisStreamsEventTarget] reader crashed', {\n type,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n function stopReader(type: string): void {\n const r = readers.get(type);\n if (r) {\n r.stop();\n readers.delete(type);\n }\n }\n\n const target: RedisStreamsEventTarget = {\n addEventListener(type, listener): void {\n let set = listeners.get(type);\n if (!set) {\n set = new Set();\n listeners.set(type, set);\n startReader(type);\n }\n set.add(listener);\n },\n removeEventListener(type, listener): void {\n const set = listeners.get(type);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) {\n listeners.delete(type);\n stopReader(type);\n }\n },\n dispatchEvent(event): boolean {\n const detail = 'detail' in event ? (event as CustomEvent).detail : event;\n void (async (): Promise<void> => {\n try {\n const payload = await serializer.stringify(detail);\n await conn.getClient().xadd(streamKey(event.type), 'MAXLEN', '~', maxLen, '*', 'payload', payload);\n } catch (err) {\n logger.error('[RedisStreamsEventTarget] dispatch failed', {\n type: event.type,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n })();\n return true;\n },\n async close(): Promise<void> {\n closed = true;\n for (const r of readers.values()) r.stop();\n readers.clear();\n listeners.clear();\n await conn.disconnect();\n },\n isHealthy(): boolean {\n return conn.isConnected();\n },\n };\n\n logger.info('[RedisStreamsEventTarget] ready', { prefix });\n return target;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { GatewayClient } from './chunk-GVZ5BDER.js';
1
+ import { GatewayClient } from './chunk-A4TGVW5V.js';
2
2
  import { __export, __name } from './chunk-XE4OXN2W.js';
3
3
 
4
4
  // src/export/index.ts
@@ -624,5 +624,5 @@ async function triggerExportJob(params) {
624
624
  __name(triggerExportJob, "triggerExportJob");
625
625
 
626
626
  export { BaseModuleExporter, PaginationService, convertToCSV, csvToJSON, estimateCSVSize, export_exports, getCSVHeaders, parseCSV, triggerExportJob };
627
- //# sourceMappingURL=chunk-GCY2FTHD.js.map
628
- //# sourceMappingURL=chunk-GCY2FTHD.js.map
627
+ //# sourceMappingURL=chunk-X5FPXATC.js.map
628
+ //# sourceMappingURL=chunk-X5FPXATC.js.map