{"version":3,"sources":["../../src/events/adapters/kafka/index.ts"],"sourcesContent":["import { KafkaJS } from '@confluentinc/kafka-javascript'\nimport { v } from 'valleyed'\n\nimport { EquippedError } from '../../../errors'\nimport { Instance } from '../../../instance'\nimport type { Events } from '../../../types'\nimport { Random, configurable, parseJSONValue } from '../../../utilities'\nimport { EventBus, type Stream, type StreamOptions } from '../base'\n\nexport const kafkaConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\tbrokers: v.array(v.string()),\n\t\t\tssl: v.optional(v.boolean()),\n\t\t\tsasl: v.optional(\n\t\t\t\tv.object({\n\t\t\t\t\tmechanism: v.is('plain' as const),\n\t\t\t\t\tusername: v.string(),\n\t\t\t\t\tpassword: v.string(),\n\t\t\t\t}),\n\t\t\t),\n\t\t\tclientId: v.optional(v.string()),\n\t\t}),\n\t\t{ title: 'Kafka Config', $refId: 'KafkaConfig' },\n\t)\n\nexport class KafkaEventBus extends configurable(kafkaConfigPipe, EventBus) {\n\t#client: KafkaJS.Kafka\n\t#admin: Promise<KafkaJS.Admin> | null = null\n\n\tprotected constructor(config: typeof KafkaEventBus.Config) {\n\t\tsuper(config)\n\t\tthis.#client = new KafkaJS.Kafka({\n\t\t\tkafkaJS: { ...config, logLevel: KafkaJS.logLevel.NOTHING },\n\t\t})\n\t}\n\n\tasync #getAdmin() {\n\t\tif (!this.#admin)\n\t\t\tthis.#admin = (async () => {\n\t\t\t\tconst admin = this.#client.admin()\n\t\t\t\tawait admin.connect()\n\t\t\t\treturn admin\n\t\t\t})()\n\t\treturn this.#admin\n\t}\n\n\tasync #createTopic(topic: string) {\n\t\tconst admin = await this.#getAdmin()\n\t\tawait admin.createTopics({ topics: [{ topic }], timeout: 5000 })\n\t}\n\n\tasync #deleteGroup(groupId: string) {\n\t\tconst admin = await this.#getAdmin()\n\t\tawait admin.deleteGroups([groupId]).catch(() => {})\n\t}\n\n\tstream<Event extends Events[keyof Events]>(topicName: Event['topic'], options: Partial<StreamOptions> = {}): Stream<Event['data']> {\n\t\tconst topic = options.skipScope ? topicName : Instance.get().getScopedName(topicName)\n\t\treturn {\n\t\t\tpublish: async (data) => {\n\t\t\t\tconst producer = this.#client.producer()\n\t\t\t\tawait producer.connect()\n\t\t\t\tawait producer.send({\n\t\t\t\t\ttopic,\n\t\t\t\t\tmessages: [{ value: JSON.stringify(data) }],\n\t\t\t\t})\n\t\t\t\treturn true\n\t\t\t},\n\t\t\tsubscribe: (onMessage) => {\n\t\t\t\tconst subscribe = async () => {\n\t\t\t\t\tawait this.#createTopic(topic)\n\t\t\t\t\tconst groupId = options.fanout\n\t\t\t\t\t\t? Instance.get().getScopedName(`${Instance.get().id}-fanout-${Random.string(10)}`)\n\t\t\t\t\t\t: topic\n\t\t\t\t\tconst consumer = this.#client.consumer({ kafkaJS: { groupId } })\n\n\t\t\t\t\tawait consumer.connect()\n\t\t\t\t\tawait consumer.subscribe({ topic })\n\n\t\t\t\t\tawait consumer.run({\n\t\t\t\t\t\teachMessage: async ({ message }) => {\n\t\t\t\t\t\t\tawait Instance.resolveBeforeCrash(async () => {\n\t\t\t\t\t\t\t\tif (!message.value) return\n\t\t\t\t\t\t\t\tawait onMessage(parseJSONValue(message.value.toString()))\n\t\t\t\t\t\t\t}).catch((error) =>\n\t\t\t\t\t\t\t\tInstance.crash(new EquippedError('Error processing kafka event', { topic, groupId, options }, error)),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tif (options.fanout)\n\t\t\t\t\t\tInstance.on('close', async () => {\n\t\t\t\t\t\t\tawait consumer.disconnect()\n\t\t\t\t\t\t\tawait this.#deleteGroup(groupId)\n\t\t\t\t\t\t}, { class: KafkaEventBus })\n\t\t\t\t}\n\t\t\t\tInstance.on('start', subscribe, { class: KafkaEventBus })\n\t\t\t},\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}