{"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":"kMAAA,OAAS,WAAAA,MAAe,iCACxB,OAAS,KAAAC,MAAS,WAQX,IAAMC,EAAkB,IAC9BC,EAAE,KACDA,EAAE,OAAO,CACR,QAASA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAC3B,IAAKA,EAAE,SAASA,EAAE,QAAQ,CAAC,EAC3B,KAAMA,EAAE,SACPA,EAAE,OAAO,CACR,UAAWA,EAAE,GAAG,OAAgB,EAChC,SAAUA,EAAE,OAAO,EACnB,SAAUA,EAAE,OAAO,CACpB,CAAC,CACF,EACA,SAAUA,EAAE,SAASA,EAAE,OAAO,CAAC,CAChC,CAAC,EACD,CAAE,MAAO,eAAgB,OAAQ,aAAc,CAChD,EAEYC,EAAN,MAAMC,UAAsBC,EAAaJ,EAAiBK,CAAQ,CAAE,CAC1EC,GACAC,GAAwC,KAE9B,YAAYC,EAAqC,CAC1D,MAAMA,CAAM,EACZ,KAAKF,GAAU,IAAIG,EAAQ,MAAM,CAChC,QAAS,CAAE,GAAGD,EAAQ,SAAUC,EAAQ,SAAS,OAAQ,CAC1D,CAAC,CACF,CAEA,KAAMC,IAAY,CACjB,OAAK,KAAKH,KACT,KAAKA,IAAU,SAAY,CAC1B,IAAMI,EAAQ,KAAKL,GAAQ,MAAM,EACjC,aAAMK,EAAM,QAAQ,EACbA,CACR,GAAG,GACG,KAAKJ,EACb,CAEA,KAAMK,GAAaC,EAAe,CAEjC,MADc,MAAM,KAAKH,GAAU,GACvB,aAAa,CAAE,OAAQ,CAAC,CAAE,MAAAG,CAAM,CAAC,EAAG,QAAS,GAAK,CAAC,CAChE,CAEA,KAAMC,GAAaC,EAAiB,CAEnC,MADc,MAAM,KAAKL,GAAU,GACvB,aAAa,CAACK,CAAO,CAAC,EAAE,MAAM,IAAM,CAAC,CAAC,CACnD,CAEA,OAA2CC,EAA2BC,EAAkC,CAAC,EAA0B,CAClI,IAAMJ,EAAQI,EAAQ,UAAYD,EAAYE,EAAS,IAAI,EAAE,cAAcF,CAAS,EACpF,MAAO,CACN,QAAS,MAAOG,GAAS,CACxB,IAAMC,EAAW,KAAKd,GAAQ,SAAS,EACvC,aAAMc,EAAS,QAAQ,EACvB,MAAMA,EAAS,KAAK,CACnB,MAAAP,EACA,SAAU,CAAC,CAAE,MAAO,KAAK,UAAUM,CAAI,CAAE,CAAC,CAC3C,CAAC,EACM,EACR,EACA,UAAYE,GAAc,CACzB,IAAMC,EAAY,SAAY,CAC7B,MAAM,KAAKV,GAAaC,CAAK,EAC7B,IAAME,EAAUE,EAAQ,OACrBC,EAAS,IAAI,EAAE,cAAc,GAAGA,EAAS,IAAI,EAAE,EAAE,WAAWK,EAAO,OAAO,EAAE,CAAC,EAAE,EAC/EV,EACGW,EAAW,KAAKlB,GAAQ,SAAS,CAAE,QAAS,CAAE,QAAAS,CAAQ,CAAE,CAAC,EAE/D,MAAMS,EAAS,QAAQ,EACvB,MAAMA,EAAS,UAAU,CAAE,MAAAX,CAAM,CAAC,EAElC,MAAMW,EAAS,IAAI,CAClB,YAAa,MAAO,CAAE,QAAAC,CAAQ,IAAM,CACnC,MAAMP,EAAS,mBAAmB,SAAY,CACxCO,EAAQ,OACb,MAAMJ,EAAUK,EAAeD,EAAQ,MAAM,SAAS,CAAC,CAAC,CACzD,CAAC,EAAE,MAAOE,GACTT,EAAS,MAAM,IAAIU,EAAc,+BAAgC,CAAE,MAAAf,EAAO,QAAAE,EAAS,QAAAE,CAAQ,EAAGU,CAAK,CAAC,CACrG,CACD,CACD,CAAC,EAEGV,EAAQ,QACXC,EAAS,GAAG,QAAS,SAAY,CAChC,MAAMM,EAAS,WAAW,EAC1B,MAAM,KAAKV,GAAaC,CAAO,CAChC,EAAG,CAAE,MAAOZ,CAAc,CAAC,CAC7B,EACAe,EAAS,GAAG,QAASI,EAAW,CAAE,MAAOnB,CAAc,CAAC,CACzD,CACD,CACD,CACD","names":["KafkaJS","v","kafkaConfigPipe","v","KafkaEventBus","_KafkaEventBus","configurable","EventBus","#client","#admin","config","KafkaJS","#getAdmin","admin","#createTopic","topic","#deleteGroup","groupId","topicName","options","Instance","data","producer","onMessage","subscribe","random_exports","consumer","message","parseJSONValue","error","EquippedError"]}