@vibesdotdev/integrations-kafka 0.0.0-stage → 1.0.0-rc.4

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 (174) hide show
  1. package/AUDIT-CODE.md +40 -0
  2. package/AUDIT-SEAL.md +12 -0
  3. package/LICENSE +126 -0
  4. package/README.md +76 -2
  5. package/SEALED.md +13 -0
  6. package/dist/admin.d.ts +20 -0
  7. package/dist/admin.d.ts.map +1 -0
  8. package/dist/admin.js +51 -0
  9. package/dist/admin.js.map +1 -0
  10. package/dist/auth/sasl.node.impl.d.ts +18 -0
  11. package/dist/auth/sasl.node.impl.d.ts.map +1 -0
  12. package/dist/auth/sasl.node.impl.js +62 -0
  13. package/dist/auth/sasl.node.impl.js.map +1 -0
  14. package/dist/chat/realtime-transport/host.d.ts +14 -0
  15. package/dist/chat/realtime-transport/host.d.ts.map +1 -0
  16. package/dist/chat/realtime-transport/host.js +7 -0
  17. package/dist/chat/realtime-transport/host.js.map +1 -0
  18. package/dist/chat/realtime-transport/index.d.ts +15 -0
  19. package/dist/chat/realtime-transport/index.d.ts.map +1 -0
  20. package/dist/chat/realtime-transport/index.js +13 -0
  21. package/dist/chat/realtime-transport/index.js.map +1 -0
  22. package/dist/chat/realtime-transport/lifecycle.d.ts +30 -0
  23. package/dist/chat/realtime-transport/lifecycle.d.ts.map +1 -0
  24. package/dist/chat/realtime-transport/lifecycle.js +125 -0
  25. package/dist/chat/realtime-transport/lifecycle.js.map +1 -0
  26. package/dist/chat/realtime-transport/projection.d.ts +127 -0
  27. package/dist/chat/realtime-transport/projection.d.ts.map +1 -0
  28. package/dist/chat/realtime-transport/projection.js +156 -0
  29. package/dist/chat/realtime-transport/projection.js.map +1 -0
  30. package/dist/chat/realtime-transport/sse-kafka-bridge.d.ts +32 -0
  31. package/dist/chat/realtime-transport/sse-kafka-bridge.d.ts.map +1 -0
  32. package/dist/chat/realtime-transport/sse-kafka-bridge.js +58 -0
  33. package/dist/chat/realtime-transport/sse-kafka-bridge.js.map +1 -0
  34. package/dist/chat/realtime-transport/ws-kafka-bridge.d.ts +10 -0
  35. package/dist/chat/realtime-transport/ws-kafka-bridge.d.ts.map +1 -0
  36. package/dist/chat/realtime-transport/ws-kafka-bridge.js +13 -0
  37. package/dist/chat/realtime-transport/ws-kafka-bridge.js.map +1 -0
  38. package/dist/client.d.ts +16 -0
  39. package/dist/client.d.ts.map +1 -0
  40. package/dist/client.js +29 -0
  41. package/dist/client.js.map +1 -0
  42. package/dist/config/kafka.config.descriptor.d.ts +109 -0
  43. package/dist/config/kafka.config.descriptor.d.ts.map +1 -0
  44. package/dist/config/kafka.config.descriptor.js +60 -0
  45. package/dist/config/kafka.config.descriptor.js.map +1 -0
  46. package/dist/connections.d.ts +27 -0
  47. package/dist/connections.d.ts.map +1 -0
  48. package/dist/connections.js +20 -0
  49. package/dist/connections.js.map +1 -0
  50. package/dist/connections.node.impl.d.ts +34 -0
  51. package/dist/connections.node.impl.d.ts.map +1 -0
  52. package/dist/connections.node.impl.js +236 -0
  53. package/dist/connections.node.impl.js.map +1 -0
  54. package/dist/index.d.ts +22 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +24 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/kafka-client.node.impl.d.ts +9 -0
  59. package/dist/kafka-client.node.impl.d.ts.map +1 -0
  60. package/dist/kafka-client.node.impl.js +10 -0
  61. package/dist/kafka-client.node.impl.js.map +1 -0
  62. package/dist/kafka-connector.impl.d.ts +53 -0
  63. package/dist/kafka-connector.impl.d.ts.map +1 -0
  64. package/dist/kafka-connector.impl.js +97 -0
  65. package/dist/kafka-connector.impl.js.map +1 -0
  66. package/dist/kafka-event-adapter.descriptor.d.ts +11 -0
  67. package/dist/kafka-event-adapter.descriptor.d.ts.map +1 -0
  68. package/dist/kafka-event-adapter.descriptor.js +20 -0
  69. package/dist/kafka-event-adapter.descriptor.js.map +1 -0
  70. package/dist/kafka-event-adapter.impl.d.ts +22 -0
  71. package/dist/kafka-event-adapter.impl.d.ts.map +1 -0
  72. package/dist/kafka-event-adapter.impl.js +140 -0
  73. package/dist/kafka-event-adapter.impl.js.map +1 -0
  74. package/dist/kafka-substrate.descriptor.d.ts +4 -0
  75. package/dist/kafka-substrate.descriptor.d.ts.map +1 -0
  76. package/dist/kafka-substrate.descriptor.js +12 -0
  77. package/dist/kafka-substrate.descriptor.js.map +1 -0
  78. package/dist/kafka.d.ts +18 -0
  79. package/dist/kafka.d.ts.map +1 -0
  80. package/dist/kafka.js +23 -0
  81. package/dist/kafka.js.map +1 -0
  82. package/dist/kafka.node.plugin.d.ts +3 -0
  83. package/dist/kafka.node.plugin.d.ts.map +1 -0
  84. package/dist/kafka.node.plugin.js +66 -0
  85. package/dist/kafka.node.plugin.js.map +1 -0
  86. package/dist/kafka.plugin.d.ts +10 -0
  87. package/dist/kafka.plugin.d.ts.map +1 -0
  88. package/dist/kafka.plugin.js +28 -0
  89. package/dist/kafka.plugin.js.map +1 -0
  90. package/dist/logging/kafka.logger.descriptor.d.ts +7 -0
  91. package/dist/logging/kafka.logger.descriptor.d.ts.map +1 -0
  92. package/dist/logging/kafka.logger.descriptor.js +13 -0
  93. package/dist/logging/kafka.logger.descriptor.js.map +1 -0
  94. package/dist/message-schemas.d.ts +94 -0
  95. package/dist/message-schemas.d.ts.map +1 -0
  96. package/dist/message-schemas.js +68 -0
  97. package/dist/message-schemas.js.map +1 -0
  98. package/dist/request-queue-timeout-guard.d.ts +29 -0
  99. package/dist/request-queue-timeout-guard.d.ts.map +1 -0
  100. package/dist/request-queue-timeout-guard.js +245 -0
  101. package/dist/request-queue-timeout-guard.js.map +1 -0
  102. package/dist/schemas/contracts.d.ts +190 -0
  103. package/dist/schemas/contracts.d.ts.map +1 -0
  104. package/dist/schemas/contracts.js +85 -0
  105. package/dist/schemas/contracts.js.map +1 -0
  106. package/dist/schemas/kafka.d.ts +116 -0
  107. package/dist/schemas/kafka.d.ts.map +1 -0
  108. package/dist/schemas/kafka.js +13 -0
  109. package/dist/schemas/kafka.js.map +1 -0
  110. package/dist/schemas/realtime.d.ts +135 -0
  111. package/dist/schemas/realtime.d.ts.map +1 -0
  112. package/dist/schemas/realtime.js +44 -0
  113. package/dist/schemas/realtime.js.map +1 -0
  114. package/dist/schemas/worker-context.d.ts +14 -0
  115. package/dist/schemas/worker-context.d.ts.map +1 -0
  116. package/dist/schemas/worker-context.js +26 -0
  117. package/dist/schemas/worker-context.js.map +1 -0
  118. package/dist/topics.d.ts +85 -0
  119. package/dist/topics.d.ts.map +1 -0
  120. package/dist/topics.js +90 -0
  121. package/dist/topics.js.map +1 -0
  122. package/dist/workers/adapter/db-ops.d.ts +28 -0
  123. package/dist/workers/adapter/db-ops.d.ts.map +1 -0
  124. package/dist/workers/adapter/db-ops.js +14 -0
  125. package/dist/workers/adapter/db-ops.js.map +1 -0
  126. package/dist/workers/adapter/index.d.ts +16 -0
  127. package/dist/workers/adapter/index.d.ts.map +1 -0
  128. package/dist/workers/adapter/index.js +15 -0
  129. package/dist/workers/adapter/index.js.map +1 -0
  130. package/dist/workers/adapter/provider.d.ts +151 -0
  131. package/dist/workers/adapter/provider.d.ts.map +1 -0
  132. package/dist/workers/adapter/provider.js +654 -0
  133. package/dist/workers/adapter/provider.js.map +1 -0
  134. package/dist/workers/adapter/worker-adapter.kafka.descriptor.d.ts +36 -0
  135. package/dist/workers/adapter/worker-adapter.kafka.descriptor.d.ts.map +1 -0
  136. package/dist/workers/adapter/worker-adapter.kafka.descriptor.js +22 -0
  137. package/dist/workers/adapter/worker-adapter.kafka.descriptor.js.map +1 -0
  138. package/dist/workers/adapter/worker-adapter.kafka.impl.d.ts +36 -0
  139. package/dist/workers/adapter/worker-adapter.kafka.impl.d.ts.map +1 -0
  140. package/dist/workers/adapter/worker-adapter.kafka.impl.js +84 -0
  141. package/dist/workers/adapter/worker-adapter.kafka.impl.js.map +1 -0
  142. package/dist/workers/adapter/workers-kafka.db.context.d.ts +6 -0
  143. package/dist/workers/adapter/workers-kafka.db.context.d.ts.map +1 -0
  144. package/dist/workers/adapter/workers-kafka.db.context.descriptor.d.ts +43 -0
  145. package/dist/workers/adapter/workers-kafka.db.context.descriptor.d.ts.map +1 -0
  146. package/dist/workers/adapter/workers-kafka.db.context.descriptor.js +20 -0
  147. package/dist/workers/adapter/workers-kafka.db.context.descriptor.js.map +1 -0
  148. package/dist/workers/adapter/workers-kafka.db.context.js +5 -0
  149. package/dist/workers/adapter/workers-kafka.db.context.js.map +1 -0
  150. package/dist/workers/index.d.ts +8 -0
  151. package/dist/workers/index.d.ts.map +1 -0
  152. package/dist/workers/index.js +9 -0
  153. package/dist/workers/index.js.map +1 -0
  154. package/dist/workers/provider-jobs.sqlite-schema.d.ts +438 -0
  155. package/dist/workers/provider-jobs.sqlite-schema.d.ts.map +1 -0
  156. package/dist/workers/provider-jobs.sqlite-schema.js +37 -0
  157. package/dist/workers/provider-jobs.sqlite-schema.js.map +1 -0
  158. package/dist/workers/shared-store.context.d.ts +25 -0
  159. package/dist/workers/shared-store.context.d.ts.map +1 -0
  160. package/dist/workers/shared-store.context.js +88 -0
  161. package/dist/workers/shared-store.context.js.map +1 -0
  162. package/dist/workers/shared-store.plugin.d.ts +8 -0
  163. package/dist/workers/shared-store.plugin.d.ts.map +1 -0
  164. package/dist/workers/shared-store.plugin.js +22 -0
  165. package/dist/workers/shared-store.plugin.js.map +1 -0
  166. package/dist/workers/workers-kafka.consumer.plugin.d.ts +4 -0
  167. package/dist/workers/workers-kafka.consumer.plugin.d.ts.map +1 -0
  168. package/dist/workers/workers-kafka.consumer.plugin.js +11 -0
  169. package/dist/workers/workers-kafka.consumer.plugin.js.map +1 -0
  170. package/dist/workers/workers-kafka.plugin.d.ts +9 -0
  171. package/dist/workers/workers-kafka.plugin.d.ts.map +1 -0
  172. package/dist/workers/workers-kafka.plugin.js +27 -0
  173. package/dist/workers/workers-kafka.plugin.js.map +1 -0
  174. package/package.json +210 -4
@@ -0,0 +1,125 @@
1
+ import { CapabilityError, settleNow, valueFreeFailure } from '@vibesdotdev/kernel';
2
+ import { createRuntimePlugin } from '@vibesdotdev/kernel/factory';
3
+ import { getLogger } from '@vibesdotdev/logging';
4
+ import { getKafkaClient } from "../../client.js";
5
+ import { KafkaConnectionPurpose } from "../../connections.js";
6
+ import { readKafkaConsumerGroupPrefix } from "../../kafka.js";
7
+ import { KAFKA_TOPICS as T } from "../../topics.js";
8
+ import { RealtimeProjection } from "./projection.js";
9
+ export class BridgeLifecycle {
10
+ runtime;
11
+ projection;
12
+ surface;
13
+ closeConnections;
14
+ consumers = new Map();
15
+ owner;
16
+ starting;
17
+ stopping;
18
+ registered = false;
19
+ active = false;
20
+ closed = false;
21
+ id = `kafka-realtime-${crypto.randomUUID()}`;
22
+ constructor(runtime, projection, surface, closeConnections) {
23
+ this.runtime = runtime;
24
+ this.projection = projection;
25
+ this.surface = surface;
26
+ this.closeConnections = closeConnections;
27
+ }
28
+ start() {
29
+ if (this.closed || this.runtime.lifecycle.signal.aborted)
30
+ return Promise.reject(new CapabilityError('Realtime bridge is disposed.', 'UNAVAILABLE', { reason: 'kafka-realtime-disposed' }));
31
+ if (this.stopping)
32
+ return this.stopping.then(() => this.start());
33
+ if (this.active)
34
+ return Promise.resolve();
35
+ return this.starting ??= this.activate();
36
+ }
37
+ async activate() {
38
+ try {
39
+ const [startup] = await Promise.allSettled([this.acquire()]);
40
+ if (startup.status === 'rejected') {
41
+ const cleanup = await Promise.allSettled([this.release()]);
42
+ const failures = cleanup.flatMap(result => result.status === 'rejected' ? [result.reason] : []);
43
+ throw new AggregateError([startup.reason, ...failures], 'Realtime startup failed');
44
+ }
45
+ }
46
+ finally {
47
+ this.starting = undefined;
48
+ }
49
+ }
50
+ async acquire() {
51
+ if (!this.registered) {
52
+ await this.runtime.registerPlugin(createRuntimePlugin({
53
+ id: this.id,
54
+ onDispose: async () => { this.closed = true; await this.stop(); }
55
+ }));
56
+ this.registered = true;
57
+ }
58
+ await this.runtime.runOutsideInvocation(async () => {
59
+ const client = await getKafkaClient(this.runtime);
60
+ this.owner = client;
61
+ const prefix = await readKafkaConsumerGroupPrefix(this.runtime, `${this.surface}-bridge`);
62
+ const groups = [
63
+ { purpose: KafkaConnectionPurpose.CHAT, topics: this.surface === 'sse'
64
+ ? [T.CHAT_MESSAGES, T.CHAT_TYPING, T.CHAT_PRESENCE, T.CHAT_ROOMS]
65
+ : [T.CHAT_MESSAGES, T.CHAT_TYPING, T.CHAT_PRESENCE] },
66
+ { purpose: KafkaConnectionPurpose.WORKERS, topics: this.surface === 'sse'
67
+ ? [T.WORKER_JOBS, T.WORKER_HEALTH, T.TEXT_GENERATION_BUBBLES, T.TEXT_GENERATION_JOBS]
68
+ : [T.WORKER_JOBS, T.WORKER_HEALTH, T.TEXT_GENERATION_BUBBLES] }
69
+ ];
70
+ for (const group of groups) {
71
+ const consumer = await client.connections.createCustomConsumer(group.purpose, `${prefix}-${group.purpose}`);
72
+ if (!consumer)
73
+ throw new CapabilityError('Kafka is unavailable in build scope.', 'UNAVAILABLE', { reason: 'kafka-build-scope' });
74
+ this.consumers.set(group.purpose === KafkaConnectionPurpose.CHAT && this.surface === 'sse' ? 'unified-chat' : group.purpose, consumer);
75
+ await consumer.subscribe({ topics: group.topics, fromBeginning: false });
76
+ await consumer.run({
77
+ autoCommit: group.purpose === KafkaConnectionPurpose.CHAT,
78
+ eachMessage: async ({ topic, message }) => {
79
+ const parsed = settleNow(() => this.projection.parse(topic, message.value?.toString() ?? ''));
80
+ if (!parsed.ok) {
81
+ getLogger('kafka:realtime', this.runtime).warn('Malformed Kafka realtime message', {
82
+ topic, failure: valueFreeFailure(parsed.cause)
83
+ });
84
+ return;
85
+ }
86
+ await this.projection.project(parsed.value);
87
+ }
88
+ });
89
+ }
90
+ });
91
+ this.active = true;
92
+ }
93
+ async release() {
94
+ if (!this.consumers.size) {
95
+ this.active = false;
96
+ this.closeConnections();
97
+ return;
98
+ }
99
+ const outcomes = await Promise.allSettled(Array.from(this.consumers.values(), consumer => this.owner.connections.releaseCustomConsumer(consumer)));
100
+ this.consumers.clear();
101
+ this.active = false;
102
+ this.closeConnections();
103
+ const failures = outcomes.flatMap(result => result.status === 'rejected' ? [result.reason] : []);
104
+ if (failures.length)
105
+ throw new AggregateError(failures, 'Realtime consumer cleanup failed');
106
+ }
107
+ stop() {
108
+ return this.stopping ??= this.deactivate();
109
+ }
110
+ async deactivate() {
111
+ try {
112
+ const startup = this.starting ? await Promise.allSettled([this.starting]) : [];
113
+ const cleanup = await Promise.allSettled([this.release()]);
114
+ const failures = [...startup, ...cleanup].flatMap(result => result.status === 'rejected' ? [result.reason] : []);
115
+ if (failures.length)
116
+ throw new AggregateError(failures, 'Realtime shutdown failed');
117
+ }
118
+ finally {
119
+ this.stopping = undefined;
120
+ }
121
+ }
122
+ isRunning() { return this.active; }
123
+ getStats() { return { active: this.active, consumers: Array.from(this.consumers.keys()), consumerCount: this.consumers.size }; }
124
+ }
125
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/chat/realtime-transport/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import { type SseMessage, type MessagePersistence } from '../../schemas/realtime.ts';
2
+ export declare function mapKafkaAgentEventType(type: string): string;
3
+ export declare class RealtimeProjection {
4
+ private readonly deliver;
5
+ private readonly websocket;
6
+ persistence?: MessagePersistence;
7
+ constructor(deliver: (channel: string, message: SseMessage) => void, websocket?: boolean);
8
+ private emit;
9
+ parse(topic: string, raw: string): {
10
+ readonly kind: "message";
11
+ readonly event: {
12
+ eventType: string;
13
+ data: {
14
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
15
+ chatRoomId: string;
16
+ userId?: string | undefined;
17
+ };
18
+ };
19
+ readonly payload?: undefined;
20
+ } | {
21
+ readonly kind: "typing";
22
+ readonly event: {
23
+ data: {
24
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
25
+ chatRoomId: string;
26
+ userId: string;
27
+ isTyping: boolean;
28
+ agentId?: string | undefined;
29
+ typingStartedAt?: string | undefined;
30
+ };
31
+ };
32
+ readonly payload?: undefined;
33
+ } | {
34
+ readonly kind: "presence";
35
+ readonly event: {
36
+ data: {
37
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
38
+ userId: string;
39
+ status: string;
40
+ lastSeen: string;
41
+ activeRooms?: string[] | undefined;
42
+ };
43
+ };
44
+ readonly payload?: undefined;
45
+ } | {
46
+ readonly kind: "room";
47
+ readonly event: {
48
+ data: {
49
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
50
+ id: string;
51
+ };
52
+ };
53
+ readonly payload?: undefined;
54
+ } | {
55
+ readonly kind: "worker";
56
+ readonly event: {
57
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
58
+ jobId: string;
59
+ jobType: string;
60
+ workerId: string;
61
+ timestamp: string;
62
+ type: "job.queued" | "job.created" | "job.started" | "job.progress" | "job.completed" | "job.failed" | "job.retrying" | "job.cancelled" | "tool.event";
63
+ id?: string | undefined;
64
+ payload?: import("@vibesdotdev/kernel/bootstrap").JsonValue | undefined;
65
+ progress?: number | Record<string, import("@vibesdotdev/kernel/bootstrap").JsonValue> | undefined;
66
+ envelope?: {
67
+ toolId: string;
68
+ toolCallId: string;
69
+ toolCallEventId: string;
70
+ payload: import("@vibesdotdev/kernel/bootstrap").JsonValue;
71
+ } | undefined;
72
+ metadata?: Record<string, import("@vibesdotdev/kernel/bootstrap").JsonValue> | undefined;
73
+ attemptNumber?: number | undefined;
74
+ error?: string | undefined;
75
+ result?: import("@vibesdotdev/kernel/bootstrap").JsonValue | undefined;
76
+ };
77
+ readonly payload: {
78
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
79
+ crawlId?: string | undefined;
80
+ id?: string | undefined;
81
+ crawl?: {
82
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
83
+ id?: string | undefined;
84
+ } | undefined;
85
+ sessionId?: string | undefined;
86
+ promptId?: string | undefined;
87
+ } | undefined;
88
+ } | {
89
+ readonly kind: "bubble";
90
+ readonly event: {
91
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
92
+ channel: string;
93
+ payload: {
94
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
95
+ chatRoomId?: string | undefined;
96
+ bubble?: {
97
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
98
+ type: string;
99
+ content?: string | undefined;
100
+ bubbleId?: string | undefined;
101
+ metadata?: {
102
+ [x: string]: import("@vibesdotdev/kernel/bootstrap").JsonValue;
103
+ messageId?: string | undefined;
104
+ agentId?: string | undefined;
105
+ toolName?: string | undefined;
106
+ toolCallId?: string | undefined;
107
+ toolArgs?: import("@vibesdotdev/kernel/bootstrap").JsonValue | undefined;
108
+ toolResult?: import("@vibesdotdev/kernel/bootstrap").JsonValue | undefined;
109
+ toolError?: import("@vibesdotdev/kernel/bootstrap").JsonValue | undefined;
110
+ timestamp?: string | undefined;
111
+ } | undefined;
112
+ } | undefined;
113
+ };
114
+ };
115
+ readonly payload?: undefined;
116
+ } | {
117
+ readonly kind: "health";
118
+ readonly event: import("@vibesdotdev/kernel/schemas/json").JsonObject;
119
+ readonly payload?: undefined;
120
+ } | {
121
+ readonly kind: "job";
122
+ readonly event: import("@vibesdotdev/kernel/schemas/json").JsonObject;
123
+ readonly payload?: undefined;
124
+ };
125
+ project(parsed: ReturnType<RealtimeProjection['parse']>): Promise<void>;
126
+ }
127
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/chat/realtime-transport/projection.ts"],"names":[],"mappings":"AAEA,OAAO,EAGN,KAAK,UAAU,EAAE,KAAK,kBAAkB,EACxC,MAAM,2BAA2B,CAAC;AAGnC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,qBAAa,kBAAkB;IAGlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAkD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFhH,WAAW,CAAC,EAAE,kBAAkB,CAAC;gBAEJ,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,KAAK,IAAI,EAAmB,SAAS,UAAQ;IAExH,OAAO,CAAC,IAAI;IAKZ,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqB1B,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;CA0F7D"}
@@ -0,0 +1,156 @@
1
+ import { CapabilityError } from '@vibesdotdev/kernel';
2
+ import { JsonValueFromReaderSchema } from '@vibesdotdev/kernel/schemas/json';
3
+ import { ChatMessageSchema, TypingSchema, PresenceSchema, RoomSchema, WorkerEventSchema, WorkerPayloadSchema, BubbleEventSchema, JsonObjectSchema, SseMessageSchema } from "../../schemas/realtime.js";
4
+ import { KAFKA_TOPICS as T } from "../../topics.js";
5
+ export function mapKafkaAgentEventType(type) {
6
+ return new Map([
7
+ ['chat.agent.chunk', 'agent_chunk'], ['chat.agent.thinking', 'agent_thinking'],
8
+ ['chat.agent.tool_call', 'agent_tool_call'], ['chat.agent.complete', 'agent_complete'],
9
+ ['chat.agent.error', 'agent_error']
10
+ ]).get(type) ?? 'agent_event';
11
+ }
12
+ export class RealtimeProjection {
13
+ deliver;
14
+ websocket;
15
+ persistence;
16
+ constructor(deliver, websocket = false) {
17
+ this.deliver = deliver;
18
+ this.websocket = websocket;
19
+ }
20
+ emit(channel, type, data) {
21
+ this.deliver(channel, SseMessageSchema.parse({ type, data: JsonValueFromReaderSchema.parse(data) }));
22
+ }
23
+ // Parse the wire payload before entering project(). Handler/persistence errors are never parse errors.
24
+ parse(topic, raw) {
25
+ const value = JSON.parse(raw);
26
+ switch (topic) {
27
+ case T.CHAT_MESSAGES: return { kind: 'message', event: ChatMessageSchema.parse(value) };
28
+ case T.CHAT_TYPING: return { kind: 'typing', event: TypingSchema.parse(value) };
29
+ case T.CHAT_PRESENCE: return { kind: 'presence', event: PresenceSchema.parse(value) };
30
+ case T.CHAT_ROOMS: return { kind: 'room', event: RoomSchema.parse(value) };
31
+ case T.WORKER_JOBS: {
32
+ const event = WorkerEventSchema.parse(value);
33
+ // Validate routing payloads here, while malformed input is still distinguishable.
34
+ const payload = event.jobType === 'crawl' || event.jobType === 'prompt-test'
35
+ ? WorkerPayloadSchema.parse(event.payload ?? {}) : undefined;
36
+ return { kind: 'worker', event, payload };
37
+ }
38
+ case T.TEXT_GENERATION_BUBBLES: return { kind: 'bubble', event: BubbleEventSchema.parse(value) };
39
+ case T.WORKER_HEALTH: return { kind: 'health', event: JsonObjectSchema.parse(value) };
40
+ case T.TEXT_GENERATION_JOBS: return { kind: 'job', event: JsonObjectSchema.parse(value) };
41
+ default: throw new CapabilityError('Unsupported realtime topic.', 'INVALID_INPUT', { reason: 'kafka-realtime-topic-invalid' });
42
+ }
43
+ }
44
+ async project(parsed) {
45
+ switch (parsed.kind) {
46
+ case 'message': {
47
+ const { eventType, data } = parsed.event;
48
+ if (eventType !== 'chat.message' && !eventType.startsWith('chat.agent.'))
49
+ return;
50
+ if (this.websocket && eventType !== 'chat.message')
51
+ return;
52
+ const type = eventType === 'chat.message' ? 'message' : mapKafkaAgentEventType(eventType);
53
+ this.emit(`chat:${data.chatRoomId}:messages`, type, data);
54
+ if (!this.websocket && eventType === 'chat.message' && data.userId)
55
+ this.emit(`user:${data.userId}:messages`, type, data);
56
+ return;
57
+ }
58
+ case 'typing':
59
+ this.emit(`chat:${parsed.event.data.chatRoomId}:typing`, 'typing', parsed.event.data);
60
+ return;
61
+ case 'presence': {
62
+ const data = parsed.event.data;
63
+ this.emit('global:presence', 'presence', data);
64
+ for (const room of data.activeRooms ?? []) {
65
+ this.emit(`chat:${room}:presence`, 'presence', this.websocket ? data : { userId: data.userId, status: data.status, lastSeen: data.lastSeen });
66
+ }
67
+ return;
68
+ }
69
+ case 'room':
70
+ this.emit(`chat:${parsed.event.data.id}:room`, 'room', parsed.event.data);
71
+ return;
72
+ case 'health':
73
+ this.emit('workers:health', 'worker_health', parsed.event);
74
+ return;
75
+ case 'job':
76
+ this.emit('workers:text-generation', 'job_status', parsed.event);
77
+ return;
78
+ case 'worker': {
79
+ const { event, payload } = parsed;
80
+ if (this.websocket) {
81
+ const crawlId = payload?.crawlId ?? payload?.id;
82
+ if (crawlId)
83
+ this.emit(`ingest:crawl:${crawlId}`, event.type || 'crawl_event', event);
84
+ this.emit('ingest:crawls', event.type || 'crawl_event', { crawlId: payload?.crawlId, jobId: event.jobId });
85
+ return;
86
+ }
87
+ if (event.type === 'tool.event' && event.envelope) {
88
+ this.emit('studio:tools', 'tool.event', { envelope: event.envelope, metadata: {
89
+ ...event.metadata, jobId: event.jobId, jobType: event.jobType, workerId: event.workerId, timestamp: event.timestamp
90
+ } });
91
+ return;
92
+ }
93
+ if (event.jobType === 'prompt-test') {
94
+ if (!payload?.sessionId || !payload.promptId)
95
+ return;
96
+ const type = new Map([
97
+ ['job.created', 'test_created'], ['job.started', 'test_started'], ['job.progress', 'test_chunk'],
98
+ ['job.completed', 'test_completed'], ['job.failed', 'test_failed'], ['job.retrying', 'test_retrying']
99
+ ]).get(event.type) ?? 'test_event';
100
+ this.emit(`prompt-test:${payload.sessionId}`, type, {
101
+ jobId: event.jobId, promptId: payload.promptId, sessionId: payload.sessionId,
102
+ chunk: payload.chunk, totalContent: payload.totalContent, tokens: payload.tokens,
103
+ responseText: payload.responseText, duration: payload.duration, promptContent: payload.promptContent,
104
+ messageChain: payload.messageChain, testResult: payload.testResult, error: event.error, timestamp: event.timestamp
105
+ });
106
+ return;
107
+ }
108
+ if (event.jobType !== 'crawl')
109
+ return;
110
+ const crawlId = payload?.crawlId ?? payload?.id ?? payload?.crawl?.id;
111
+ if (!crawlId)
112
+ return;
113
+ const type = new Map([
114
+ ['job.queued', 'crawl_queued'], ['job.created', 'crawl_created'], ['job.started', 'crawl_started'],
115
+ ['job.progress', 'crawl_progress'], ['job.completed', 'crawl_completed'], ['job.failed', 'crawl_failed'],
116
+ ['job.retrying', 'crawl_retrying'], ['tool.event', 'crawl_tool_event']
117
+ ]).get(event.type) ?? 'crawl_event';
118
+ this.emit(`ingest:crawl:${crawlId}`, type, {
119
+ crawlId, jobId: event.jobId, progress: event.progress, payload: event.payload,
120
+ error: event.error, attemptNumber: event.attemptNumber, timestamp: event.timestamp
121
+ });
122
+ this.emit('ingest:crawls', type, { crawlId, jobId: event.jobId, jobType: event.jobType, progress: event.progress, timestamp: event.timestamp });
123
+ return;
124
+ }
125
+ case 'bubble': {
126
+ const event = parsed.event;
127
+ const { chatRoomId, bubble } = event.payload;
128
+ if (!chatRoomId)
129
+ return;
130
+ if (this.websocket) {
131
+ this.emit(`chat:${chatRoomId}:messages`, 'agent_chunk', event);
132
+ return;
133
+ }
134
+ if (event.channel !== 'chat' || !bubble)
135
+ return;
136
+ const metadata = bubble.metadata ?? {};
137
+ const { content, type } = bubble;
138
+ const data = { chatRoomId, messageId: metadata.messageId, agentId: metadata.agentId, content };
139
+ if (type === 'complete') {
140
+ if (this.persistence && metadata.messageId && content)
141
+ await this.persistence.updateMessage(metadata.messageId, content);
142
+ this.emit(`chat:${chatRoomId}:messages`, 'agent_complete', { ...data, metadata });
143
+ }
144
+ else if (type === 'error') {
145
+ this.emit(`chat:${chatRoomId}:messages`, 'agent_error', { ...data, error: content, metadata });
146
+ }
147
+ else if (['thinking', 'tool_call', 'tool_response', 'content'].includes(type)) {
148
+ this.emit(`chat:${chatRoomId}:messages`, 'agent_chunk', {
149
+ ...data, metadata: { chunkType: type, bubbleId: bubble.bubbleId ?? `${Date.now()}`, ...metadata }
150
+ });
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/chat/realtime-transport/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { type VibesRuntime } from '@vibesdotdev/kernel';
2
+ import type { ReadonlyJsonObject } from '@vibesdotdev/kernel/schemas/json';
3
+ import { type MessagePersistence, type SseMessage } from '../../schemas/realtime.ts';
4
+ import { type SseBridgeHost } from './host.ts';
5
+ export { mapKafkaAgentEventType } from './projection.ts';
6
+ export type { SseMessage } from '../../schemas/realtime.ts';
7
+ export interface SseBridgeConnection {
8
+ accepts(channel: string, message: SseMessage): boolean;
9
+ push(channel: string, message: SseMessage): void;
10
+ }
11
+ export declare class SSEKafkaBridge {
12
+ private readonly runtime;
13
+ private host;
14
+ private readonly connections;
15
+ private readonly projection;
16
+ private readonly lifecycle;
17
+ constructor(runtime: VibesRuntime, host?: SseBridgeHost);
18
+ openConnection(runtime: VibesRuntime, connection: SseBridgeConnection): () => void;
19
+ private deliver;
20
+ setHost(host: SseBridgeHost): void;
21
+ /** Persistence is optional. Legacy database objects cannot pretend to persist. */
22
+ configure(deps: MessagePersistence | ReadonlyJsonObject): void;
23
+ start(): Promise<void>;
24
+ stop(): Promise<void>;
25
+ isRunning(): boolean;
26
+ getStats(): {
27
+ active: boolean;
28
+ consumers: string[];
29
+ consumerCount: number;
30
+ };
31
+ }
32
+ //# sourceMappingURL=sse-kafka-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-kafka-bridge.d.ts","sourceRoot":"","sources":["../../../src/chat/realtime-transport/sse-kafka-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2E,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACjI,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC/G,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAIzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CACjD;AAMD,qBAAa,cAAc;IAKd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAgB,OAAO,CAAC,IAAI;IAJhE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAEf,OAAO,EAAE,YAAY,EAAU,IAAI,GAAE,aAAwC;IAK1G,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAMlF,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,IAAI,EAAE,aAAa;IAE3B,kFAAkF;IAClF,SAAS,CAAC,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,IAAI;IAM9D,KAAK;IACL,IAAI;IACJ,SAAS;IACT,QAAQ;;;;;CACR"}
@@ -0,0 +1,58 @@
1
+ import { CapabilityError, settleNow } from '@vibesdotdev/kernel';
2
+ import { MessagePersistenceSchema } from "../../schemas/realtime.js";
3
+ import { unavailableSseBridgeHost } from "./host.js";
4
+ import { RealtimeProjection } from "./projection.js";
5
+ import { BridgeLifecycle } from "./lifecycle.js";
6
+ export { mapKafkaAgentEventType } from "./projection.js";
7
+ export class SSEKafkaBridge {
8
+ runtime;
9
+ host;
10
+ connections = new Set();
11
+ projection;
12
+ lifecycle;
13
+ constructor(runtime, host = unavailableSseBridgeHost) {
14
+ this.runtime = runtime;
15
+ this.host = host;
16
+ this.projection = new RealtimeProjection((channel, message) => this.deliver(channel, message));
17
+ this.lifecycle = new BridgeLifecycle(runtime, this.projection, 'sse', () => this.connections.clear());
18
+ }
19
+ openConnection(runtime, connection) {
20
+ const open = { connection, invocation: runtime.captureInvocation() };
21
+ this.connections.add(open);
22
+ return () => { this.connections.delete(open); };
23
+ }
24
+ deliver(channel, message) {
25
+ // Synchronous connection delivery must visit every connection even when one fails.
26
+ const failures = [];
27
+ const host = settleNow(() => this.host.broadcastToChannel(channel, message));
28
+ if (!host.ok)
29
+ failures.push(host.cause);
30
+ for (const open of this.connections) {
31
+ const delivery = settleNow(() => open.invocation.run(() => {
32
+ if (open.connection.accepts(channel, message))
33
+ open.connection.push(channel, message);
34
+ }));
35
+ if (!delivery.ok) {
36
+ this.connections.delete(open);
37
+ failures.push(delivery.cause);
38
+ }
39
+ }
40
+ if (failures.length === 1)
41
+ throw failures[0];
42
+ if (failures.length)
43
+ throw new AggregateError(failures, 'Realtime delivery failed');
44
+ }
45
+ setHost(host) { this.host = host; }
46
+ /** Persistence is optional. Legacy database objects cannot pretend to persist. */
47
+ configure(deps) {
48
+ const parsed = MessagePersistenceSchema.safeParse(deps);
49
+ if (!parsed.success)
50
+ throw new CapabilityError('Supply the message persistence owner capability.', 'UNAVAILABLE', { reason: 'kafka-realtime-persistence-unavailable' });
51
+ this.projection.persistence = parsed.data;
52
+ }
53
+ start() { return this.lifecycle.start(); }
54
+ stop() { return this.lifecycle.stop(); }
55
+ isRunning() { return this.lifecycle.isRunning(); }
56
+ getStats() { return this.lifecycle.getStats(); }
57
+ }
58
+ //# sourceMappingURL=sse-kafka-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-kafka-bridge.js","sourceRoot":"","sources":["../../../src/chat/realtime-transport/sse-kafka-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { VibesRuntime } from '@vibesdotdev/kernel';
2
+ import type { WebSocketBridgeHost } from './host.ts';
3
+ export declare class WSKafkaBridge {
4
+ private readonly lifecycle;
5
+ constructor(runtime: VibesRuntime, adapter: WebSocketBridgeHost);
6
+ start(): Promise<void>;
7
+ stop(): Promise<void>;
8
+ isRunning(): boolean;
9
+ }
10
+ //# sourceMappingURL=ws-kafka-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-kafka-bridge.d.ts","sourceRoot":"","sources":["../../../src/chat/realtime-transport/ws-kafka-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAIrD,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAChC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB;IAI/D,KAAK;IACL,IAAI;IACJ,SAAS;CACT"}
@@ -0,0 +1,13 @@
1
+ import { RealtimeProjection } from "./projection.js";
2
+ import { BridgeLifecycle } from "./lifecycle.js";
3
+ export class WSKafkaBridge {
4
+ lifecycle;
5
+ constructor(runtime, adapter) {
6
+ const projection = new RealtimeProjection((channel, message) => { adapter.broadcast(channel, message); }, true);
7
+ this.lifecycle = new BridgeLifecycle(runtime, projection, 'ws', () => { });
8
+ }
9
+ start() { return this.lifecycle.start(); }
10
+ stop() { return this.lifecycle.stop(); }
11
+ isRunning() { return this.lifecycle.isRunning(); }
12
+ }
13
+ //# sourceMappingURL=ws-kafka-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-kafka-bridge.js","sourceRoot":"","sources":["../../../src/chat/realtime-transport/ws-kafka-bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,OAAO,aAAa;IACR,SAAS,CAAkB;IAC5C,YAAY,OAAqB,EAAE,OAA4B;QAC9D,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAChH,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,KAAK,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1C,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,SAAS,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;CAClD"}
@@ -0,0 +1,16 @@
1
+ import { type VibesRuntime, type RuntimeRef } from '@vibesdotdev/kernel';
2
+ import { BaseRuntimeClient } from '@vibesdotdev/kernel/client';
3
+ import type { EventAdapter } from '@vibesdotdev/kernel/events';
4
+ import type { KafkaConnections } from './connections.node.impl.ts';
5
+ import { KafkaAdmin } from './admin.ts';
6
+ /** Semantic owner; the Node plugin supplies its connection implementation. */
7
+ export declare abstract class KafkaClient extends BaseRuntimeClient<VibesRuntime> {
8
+ abstract readonly connections: KafkaConnections;
9
+ readonly admin: KafkaAdmin;
10
+ private readonly adapters;
11
+ ownAdapter(adapter: EventAdapter): void;
12
+ protected onDispose(): Promise<void>;
13
+ }
14
+ export declare const getKafkaClient: (runtime: RuntimeRef) => Promise<KafkaClient>;
15
+ export declare function requireKafkaClient(runtime: VibesRuntime): KafkaClient;
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAqC,MAAM,4BAA4B,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,8EAA8E;AAC9E,8BAAsB,WAAY,SAAQ,iBAAiB,CAAC,YAAY,CAAC;IACxE,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IAChD,QAAQ,CAAC,KAAK,aAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAEpD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;cAKvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAO1C;AAED,eAAO,MAAM,cAAc,GAAI,SAAS,UAAU,yBAAkD,CAAC;AAErG,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CAIrE"}
package/dist/client.js ADDED
@@ -0,0 +1,29 @@
1
+ import { CapabilityError } from '@vibesdotdev/kernel';
2
+ import { BaseRuntimeClient, getVibesClient, tryGetVibesClient } from '@vibesdotdev/kernel/client';
3
+ import { KafkaAdmin } from "./admin.js";
4
+ /** Semantic owner; the Node plugin supplies its connection implementation. */
5
+ export class KafkaClient extends BaseRuntimeClient {
6
+ admin = new KafkaAdmin(this.runtime);
7
+ adapters = new Set();
8
+ ownAdapter(adapter) {
9
+ if (this.runtime.lifecycle.signal.aborted)
10
+ throw new CapabilityError('Kafka runtime is disposed.', 'UNAVAILABLE', { reason: 'kafka-client-disposed' });
11
+ this.adapters.add(adapter);
12
+ }
13
+ async onDispose() {
14
+ const outcomes = await Promise.allSettled(Array.from(this.adapters, adapter => adapter.disconnect()));
15
+ this.adapters.clear();
16
+ const connections = await Promise.allSettled([this.connections.dispose()]);
17
+ const failures = [...outcomes, ...connections].flatMap(outcome => outcome.status === 'rejected' ? [outcome.reason] : []);
18
+ if (failures.length)
19
+ throw new AggregateError(failures, 'Kafka runtime cleanup failed');
20
+ }
21
+ }
22
+ export const getKafkaClient = (runtime) => getVibesClient('kafka', runtime);
23
+ export function requireKafkaClient(runtime) {
24
+ const client = tryGetVibesClient('kafka', runtime);
25
+ if (!client)
26
+ throw new CapabilityError('Activate the Kafka runtime client before synchronous access.', 'UNAVAILABLE', { reason: 'kafka-client-not-active' });
27
+ return client;
28
+ }
29
+ //# sourceMappingURL=client.js.map