@absolutejs/absolute 0.19.0-beta.226 → 0.19.0-beta.227

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 (75) hide show
  1. package/.absolutejs/eslint-cache +1 -0
  2. package/.absolutejs/prettier.cache.json +42 -19
  3. package/.absolutejs/vue-tsc.tsbuildinfo +1 -1
  4. package/.claude/settings.local.json +2 -1
  5. package/ROADMAP.md +0 -25
  6. package/dist/{Image-y5bdvj57.vue → Image-b3r6hxqk.vue} +6 -1
  7. package/dist/ai/index.js +529 -0
  8. package/dist/ai/index.js.map +13 -0
  9. package/dist/ai/providers/anthropic.js +396 -0
  10. package/dist/ai/providers/anthropic.js.map +10 -0
  11. package/dist/ai/providers/ollama.js +233 -0
  12. package/dist/ai/providers/ollama.js.map +10 -0
  13. package/dist/ai/providers/openai.js +355 -0
  14. package/dist/ai/providers/openai.js.map +10 -0
  15. package/dist/ai-client/angular/ai/index.js +532 -0
  16. package/dist/ai-client/react/ai/index.js +499 -0
  17. package/dist/ai-client/vue/ai/index.js +460 -0
  18. package/dist/angular/ai/index.js +668 -0
  19. package/dist/angular/ai/index.js.map +15 -0
  20. package/dist/angular/components/image.component.js +1 -1
  21. package/dist/angular/index.js +11 -1
  22. package/dist/angular/index.js.map +3 -3
  23. package/dist/build.js +48 -2
  24. package/dist/build.js.map +4 -4
  25. package/dist/index.js +50 -2
  26. package/dist/index.js.map +6 -6
  27. package/dist/react/ai/index.js +635 -0
  28. package/dist/react/ai/index.js.map +16 -0
  29. package/dist/react/components/index.js +11 -1
  30. package/dist/react/components/index.js.map +2 -2
  31. package/dist/react/hooks/index.js +11 -1
  32. package/dist/react/hooks/index.js.map +2 -2
  33. package/dist/react/index.js +11 -1
  34. package/dist/react/index.js.map +3 -3
  35. package/dist/src/ai/client/actions.d.ts +46 -0
  36. package/dist/src/ai/client/connection.d.ts +9 -0
  37. package/dist/src/ai/client/messageStore.d.ts +12 -0
  38. package/dist/src/ai/conversationManager.d.ts +11 -0
  39. package/dist/src/ai/index.d.ts +3 -0
  40. package/dist/src/ai/protocol.d.ts +4 -0
  41. package/dist/src/ai/providers/anthropic.d.ts +3 -0
  42. package/dist/src/ai/providers/ollama.d.ts +6 -0
  43. package/dist/src/ai/providers/openai.d.ts +7 -0
  44. package/dist/src/ai/streamAI.d.ts +2 -0
  45. package/dist/src/angular/ai/ai-stream.service.d.ts +15 -0
  46. package/dist/src/angular/ai/index.d.ts +1 -0
  47. package/dist/src/react/ai/AIStreamProvider.d.ts +13 -0
  48. package/dist/src/react/ai/index.d.ts +2 -0
  49. package/dist/src/react/ai/useAIStream.d.ts +8 -0
  50. package/dist/src/svelte/ai/createAIStream.d.ts +10 -0
  51. package/dist/src/svelte/ai/index.d.ts +1 -0
  52. package/dist/src/vue/ai/index.d.ts +1 -0
  53. package/dist/src/vue/ai/useAIStream.d.ts +22 -0
  54. package/dist/svelte/ai/index.js +590 -0
  55. package/dist/svelte/ai/index.js.map +15 -0
  56. package/dist/svelte/components/Image.svelte +6 -1
  57. package/dist/svelte/index.js +11 -1
  58. package/dist/svelte/index.js.map +3 -3
  59. package/dist/types/ai.d.ts +188 -0
  60. package/dist/types/anthropic.d.ts +18 -0
  61. package/dist/types/index.d.ts +1 -0
  62. package/dist/types/typeGuards.d.ts +3 -0
  63. package/dist/vue/ai/index.js +596 -0
  64. package/dist/vue/ai/index.js.map +15 -0
  65. package/dist/vue/components/Image.vue +6 -1
  66. package/dist/vue/components/index.js +12 -2
  67. package/dist/vue/components/index.js.map +1 -1
  68. package/dist/vue/index.js +11 -1
  69. package/dist/vue/index.js.map +3 -3
  70. package/package.json +36 -1
  71. package/scripts/build.ts +33 -0
  72. package/types/ai.ts +235 -0
  73. package/types/anthropic.ts +17 -0
  74. package/types/index.ts +1 -0
  75. package/types/typeGuards.ts +72 -1
@@ -0,0 +1,668 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __toCommonJS = (from) => {
34
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
35
+ if (entry)
36
+ return entry;
37
+ entry = __defProp({}, "__esModule", { value: true });
38
+ if (from && typeof from === "object" || typeof from === "function") {
39
+ for (var key of __getOwnPropNames(from))
40
+ if (!__hasOwnProp.call(entry, key))
41
+ __defProp(entry, key, {
42
+ get: __accessProp.bind(from, key),
43
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
44
+ });
45
+ }
46
+ __moduleCache.set(from, entry);
47
+ return entry;
48
+ };
49
+ var __moduleCache;
50
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
51
+ var __returnValue = (v) => v;
52
+ function __exportSetter(name, newValue) {
53
+ this[name] = __returnValue.bind(null, newValue);
54
+ }
55
+ var __export = (target, all) => {
56
+ for (var name in all)
57
+ __defProp(target, name, {
58
+ get: all[name],
59
+ enumerable: true,
60
+ configurable: true,
61
+ set: __exportSetter.bind(all, name)
62
+ });
63
+ };
64
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
65
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
66
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
67
+ r = Reflect.decorate(decorators, target, key, desc);
68
+ else
69
+ for (var i = decorators.length - 1;i >= 0; i--)
70
+ if (d = decorators[i])
71
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
72
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
73
+ };
74
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
75
+ var __require = import.meta.require;
76
+
77
+ // types/typeGuards.ts
78
+ var isValidAIClientMessage = (data) => {
79
+ if (!data || typeof data !== "object") {
80
+ return false;
81
+ }
82
+ if (!("type" in data) || typeof data.type !== "string") {
83
+ return false;
84
+ }
85
+ switch (data.type) {
86
+ case "message":
87
+ return "content" in data && typeof data.content === "string";
88
+ case "cancel":
89
+ return "conversationId" in data && typeof data.conversationId === "string";
90
+ case "branch":
91
+ return "messageId" in data && typeof data.messageId === "string" && "content" in data && typeof data.content === "string" && "conversationId" in data && typeof data.conversationId === "string";
92
+ default:
93
+ return false;
94
+ }
95
+ }, isValidAIServerMessage = (data) => {
96
+ if (!data || typeof data !== "object") {
97
+ return false;
98
+ }
99
+ if (!("type" in data) || typeof data.type !== "string") {
100
+ return false;
101
+ }
102
+ switch (data.type) {
103
+ case "chunk":
104
+ return "content" in data && typeof data.content === "string" && "messageId" in data && "conversationId" in data;
105
+ case "tool_status":
106
+ return "name" in data && "status" in data && "messageId" in data && "conversationId" in data;
107
+ case "complete":
108
+ return "messageId" in data && "conversationId" in data;
109
+ case "error":
110
+ return "message" in data && typeof data.message === "string";
111
+ default:
112
+ return false;
113
+ }
114
+ }, isValidHMRClientMessage = (data) => {
115
+ if (!data || typeof data !== "object") {
116
+ return false;
117
+ }
118
+ if (!("type" in data) || typeof data.type !== "string") {
119
+ return false;
120
+ }
121
+ switch (data.type) {
122
+ case "ping":
123
+ return true;
124
+ case "ready":
125
+ return true;
126
+ case "request-rebuild":
127
+ return true;
128
+ case "hydration-error":
129
+ return true;
130
+ case "hmr-timing":
131
+ return true;
132
+ default:
133
+ return false;
134
+ }
135
+ };
136
+
137
+ // src/angular/ai/ai-stream.service.ts
138
+ import { computed, Injectable, signal } from "@angular/core";
139
+
140
+ // src/ai/client/actions.ts
141
+ var serverMessageToAction = (msg) => {
142
+ switch (msg.type) {
143
+ case "chunk":
144
+ return {
145
+ content: msg.content,
146
+ conversationId: msg.conversationId,
147
+ messageId: msg.messageId,
148
+ type: "chunk"
149
+ };
150
+ case "tool_status":
151
+ return {
152
+ conversationId: msg.conversationId,
153
+ input: msg.input,
154
+ messageId: msg.messageId,
155
+ name: msg.name,
156
+ result: msg.result,
157
+ status: msg.status,
158
+ type: "tool_status"
159
+ };
160
+ case "complete":
161
+ return {
162
+ conversationId: msg.conversationId,
163
+ messageId: msg.messageId,
164
+ type: "complete",
165
+ usage: msg.usage
166
+ };
167
+ case "error":
168
+ return { message: msg.message, type: "error" };
169
+ default:
170
+ return null;
171
+ }
172
+ };
173
+
174
+ // src/ai/client/connection.ts
175
+ var WS_OPEN = 1;
176
+ var WS_NORMAL_CLOSURE = 1000;
177
+ var WS_CLOSED = 3;
178
+ var DEFAULT_PING_INTERVAL = 30000;
179
+ var RECONNECT_INITIAL_DELAY = 500;
180
+ var RECONNECT_POLL_INTERVAL = 300;
181
+ var DEFAULT_MAX_RECONNECT_ATTEMPTS = 60;
182
+ var noop = () => {};
183
+ var noopUnsubscribe = () => noop;
184
+ var NOOP_CONNECTION = {
185
+ close: noop,
186
+ send: noop,
187
+ subscribe: noopUnsubscribe,
188
+ getReadyState: () => WS_CLOSED
189
+ };
190
+ var buildWsUrl = (path) => {
191
+ const { hostname, port, protocol } = window.location;
192
+ const wsProtocol = protocol === "https:" ? "wss:" : "ws:";
193
+ const portSuffix = port ? `:${port}` : "";
194
+ return `${wsProtocol}//${hostname}${portSuffix}${path}`;
195
+ };
196
+ var parseServerMessage = (event) => {
197
+ let data;
198
+ try {
199
+ data = JSON.parse(String(event.data));
200
+ } catch {
201
+ return null;
202
+ }
203
+ if (data && typeof data === "object" && "type" in data && data.type === "pong") {
204
+ return null;
205
+ }
206
+ if (!isValidAIServerMessage(data)) {
207
+ return null;
208
+ }
209
+ return data;
210
+ };
211
+ var createAIConnection = (path, options = {}) => {
212
+ if (typeof window === "undefined") {
213
+ return NOOP_CONNECTION;
214
+ }
215
+ const shouldReconnect = options.reconnect !== false;
216
+ const pingInterval = options.pingInterval ?? DEFAULT_PING_INTERVAL;
217
+ const maxReconnectAttempts = options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;
218
+ const listeners = new Set;
219
+ const connState = {
220
+ isConnected: false,
221
+ pingInterval: null,
222
+ reconnectAttempts: 0,
223
+ reconnectTimeout: null,
224
+ ws: null
225
+ };
226
+ const clearTimers = () => {
227
+ if (connState.pingInterval) {
228
+ clearInterval(connState.pingInterval);
229
+ connState.pingInterval = null;
230
+ }
231
+ if (connState.reconnectTimeout) {
232
+ clearTimeout(connState.reconnectTimeout);
233
+ connState.reconnectTimeout = null;
234
+ }
235
+ };
236
+ const scheduleReconnect = () => {
237
+ connState.reconnectAttempts++;
238
+ const delay = connState.reconnectAttempts === 1 ? RECONNECT_INITIAL_DELAY : RECONNECT_POLL_INTERVAL;
239
+ connState.reconnectTimeout = setTimeout(() => {
240
+ if (connState.reconnectAttempts > maxReconnectAttempts) {
241
+ return;
242
+ }
243
+ connect();
244
+ }, delay);
245
+ };
246
+ const connect = () => {
247
+ const url = buildWsUrl(path);
248
+ const wsInstance = new WebSocket(url, options.protocols);
249
+ wsInstance.onopen = () => {
250
+ connState.isConnected = true;
251
+ connState.reconnectAttempts = 0;
252
+ connState.pingInterval = setInterval(() => {
253
+ if (wsInstance.readyState === WS_OPEN && connState.isConnected) {
254
+ wsInstance.send(JSON.stringify({ type: "ping" }));
255
+ }
256
+ }, pingInterval);
257
+ };
258
+ wsInstance.onmessage = (event) => {
259
+ const message = parseServerMessage(event);
260
+ if (!message) {
261
+ return;
262
+ }
263
+ listeners.forEach((listener) => listener(message));
264
+ };
265
+ wsInstance.onclose = (event) => {
266
+ connState.isConnected = false;
267
+ clearTimers();
268
+ const shouldAttemptReconnect = shouldReconnect && event.code !== WS_NORMAL_CLOSURE && connState.reconnectAttempts < maxReconnectAttempts;
269
+ if (shouldAttemptReconnect) {
270
+ scheduleReconnect();
271
+ }
272
+ };
273
+ wsInstance.onerror = () => {};
274
+ connState.ws = wsInstance;
275
+ };
276
+ const send = (msg) => {
277
+ if (connState.ws?.readyState === WS_OPEN) {
278
+ connState.ws.send(JSON.stringify(msg));
279
+ }
280
+ };
281
+ const subscribe = (callback) => {
282
+ listeners.add(callback);
283
+ return () => {
284
+ listeners.delete(callback);
285
+ };
286
+ };
287
+ const close = () => {
288
+ clearTimers();
289
+ if (connState.ws) {
290
+ connState.ws.close(WS_NORMAL_CLOSURE);
291
+ connState.ws = null;
292
+ }
293
+ connState.isConnected = false;
294
+ listeners.clear();
295
+ };
296
+ const getReadyState = () => connState.ws?.readyState ?? WS_CLOSED;
297
+ connect();
298
+ return { close, getReadyState, send, subscribe };
299
+ };
300
+
301
+ // src/ai/client/messageStore.ts
302
+ var EMPTY_STATE = {
303
+ activeConversationId: null,
304
+ conversations: new Map,
305
+ error: null,
306
+ isStreaming: false
307
+ };
308
+ var initialActiveConversationId = null;
309
+ var initialError = null;
310
+ var freshState = () => ({
311
+ activeConversationId: initialActiveConversationId,
312
+ conversations: new Map,
313
+ error: initialError,
314
+ isStreaming: false
315
+ });
316
+ var findAssistantMessage = (conversation, messageId) => conversation.messages.find((msg) => msg.id === messageId && msg.role === "assistant");
317
+ var getOrCreate = (state, conversationId) => {
318
+ let conversation = state.conversations.get(conversationId);
319
+ if (!conversation) {
320
+ conversation = { id: conversationId, messages: [] };
321
+ state.conversations.set(conversationId, conversation);
322
+ }
323
+ return conversation;
324
+ };
325
+ var handleSend = (state, action) => {
326
+ const conversation = getOrCreate(state, action.conversationId);
327
+ const message = {
328
+ content: action.content,
329
+ conversationId: action.conversationId,
330
+ id: action.messageId,
331
+ role: "user",
332
+ timestamp: Date.now()
333
+ };
334
+ conversation.messages = [...conversation.messages, message];
335
+ state.activeConversationId = action.conversationId;
336
+ state.error = null;
337
+ state.isStreaming = true;
338
+ };
339
+ var handleChunk = (state, action) => {
340
+ const conversation = getOrCreate(state, action.conversationId);
341
+ const existing = findAssistantMessage(conversation, action.messageId);
342
+ if (existing) {
343
+ existing.content += action.content;
344
+ conversation.messages = [...conversation.messages];
345
+ return;
346
+ }
347
+ const message = {
348
+ content: action.content,
349
+ conversationId: action.conversationId,
350
+ id: action.messageId,
351
+ isStreaming: true,
352
+ role: "assistant",
353
+ timestamp: Date.now()
354
+ };
355
+ conversation.messages = [...conversation.messages, message];
356
+ };
357
+ var upsertToolCall = (message, toolCall) => {
358
+ if (!message.toolCalls) {
359
+ message.toolCalls = [toolCall];
360
+ return;
361
+ }
362
+ const existingIdx = message.toolCalls.findIndex((existing) => existing.name === toolCall.name);
363
+ if (existingIdx >= 0) {
364
+ message.toolCalls[existingIdx] = toolCall;
365
+ } else {
366
+ message.toolCalls = [...message.toolCalls, toolCall];
367
+ }
368
+ };
369
+ var handleToolStatus = (state, action) => {
370
+ const conversation = getOrCreate(state, action.conversationId);
371
+ const message = findAssistantMessage(conversation, action.messageId);
372
+ if (!message) {
373
+ return;
374
+ }
375
+ const toolCall = {
376
+ id: action.messageId,
377
+ input: action.input,
378
+ name: action.name,
379
+ result: action.status === "complete" ? action.result ?? "" : undefined
380
+ };
381
+ upsertToolCall(message, toolCall);
382
+ conversation.messages = [...conversation.messages];
383
+ };
384
+ var markMessageComplete = (conversation, messageId) => {
385
+ const message = findAssistantMessage(conversation, messageId);
386
+ if (message) {
387
+ message.isStreaming = false;
388
+ }
389
+ conversation.messages = [...conversation.messages];
390
+ };
391
+ var handleComplete = (state, action) => {
392
+ const conversation = state.conversations.get(action.conversationId);
393
+ if (conversation) {
394
+ markMessageComplete(conversation, action.messageId);
395
+ }
396
+ state.isStreaming = false;
397
+ };
398
+ var markConversationStreamsComplete = (conversation) => {
399
+ const streamingMessages = conversation.messages.filter((msg) => msg.isStreaming);
400
+ if (streamingMessages.length === 0) {
401
+ return;
402
+ }
403
+ for (const msg of streamingMessages) {
404
+ msg.isStreaming = false;
405
+ }
406
+ conversation.messages = [...conversation.messages];
407
+ };
408
+ var markAllStreamsComplete = (state) => {
409
+ for (const [, conversation] of state.conversations) {
410
+ markConversationStreamsComplete(conversation);
411
+ }
412
+ };
413
+ var handleBranch = (state, action) => {
414
+ const source = state.conversations.get(action.oldConversationId);
415
+ if (!source) {
416
+ return;
417
+ }
418
+ const cutoffIndex = source.messages.findIndex((msg) => msg.id === action.fromMessageId);
419
+ if (cutoffIndex < 0) {
420
+ return;
421
+ }
422
+ const branchedMessages = source.messages.slice(0, cutoffIndex + 1).map((msg) => ({ ...msg, conversationId: action.newConversationId }));
423
+ const newConversation = {
424
+ id: action.newConversationId,
425
+ messages: branchedMessages
426
+ };
427
+ state.conversations.set(action.newConversationId, newConversation);
428
+ state.activeConversationId = action.newConversationId;
429
+ };
430
+ var dispatch = (state, subscribers, action) => {
431
+ switch (action.type) {
432
+ case "send":
433
+ handleSend(state, action);
434
+ break;
435
+ case "chunk":
436
+ handleChunk(state, action);
437
+ break;
438
+ case "tool_status":
439
+ handleToolStatus(state, action);
440
+ break;
441
+ case "complete":
442
+ handleComplete(state, action);
443
+ break;
444
+ case "error":
445
+ state.error = action.message;
446
+ state.isStreaming = false;
447
+ break;
448
+ case "cancel":
449
+ state.isStreaming = false;
450
+ markAllStreamsComplete(state);
451
+ break;
452
+ case "branch":
453
+ handleBranch(state, action);
454
+ break;
455
+ case "set_conversation":
456
+ state.activeConversationId = action.conversationId;
457
+ break;
458
+ }
459
+ Object.assign(state, { conversations: new Map(state.conversations) });
460
+ subscribers.forEach((callback) => callback());
461
+ };
462
+ var createAIMessageStore = () => {
463
+ const state = freshState();
464
+ const subscribers = new Set;
465
+ return {
466
+ dispatch: (action) => dispatch(state, subscribers, action),
467
+ getServerSnapshot: () => EMPTY_STATE,
468
+ getSnapshot: () => state,
469
+ subscribe: (callback) => {
470
+ subscribers.add(callback);
471
+ return () => {
472
+ subscribers.delete(callback);
473
+ };
474
+ }
475
+ };
476
+ };
477
+
478
+ // src/ai/protocol.ts
479
+ var generateId = () => crypto.randomUUID();
480
+ var parseAIMessage = (raw) => {
481
+ if (raw === null || raw === undefined) {
482
+ return null;
483
+ }
484
+ let text;
485
+ if (typeof raw === "string") {
486
+ text = raw;
487
+ } else if (raw instanceof ArrayBuffer) {
488
+ text = new TextDecoder().decode(raw);
489
+ } else if (ArrayBuffer.isView(raw)) {
490
+ text = new TextDecoder().decode(raw);
491
+ } else if (typeof raw === "object") {
492
+ if (isValidAIClientMessage(raw)) {
493
+ return raw;
494
+ }
495
+ return null;
496
+ } else {
497
+ return null;
498
+ }
499
+ try {
500
+ const parsed = JSON.parse(text);
501
+ if (isValidAIClientMessage(parsed)) {
502
+ return parsed;
503
+ }
504
+ return null;
505
+ } catch {
506
+ return null;
507
+ }
508
+ };
509
+ var serializeAIMessage = (msg) => JSON.stringify(msg);
510
+
511
+ // src/angular/ai/ai-stream.service.ts
512
+ class AIStreamService {
513
+ connections = new Map;
514
+ connect(path, conversationId) {
515
+ const existing = this.connections.get(path);
516
+ if (existing) {
517
+ return this.createHandle(existing, conversationId);
518
+ }
519
+ const connection = createAIConnection(path);
520
+ const store = createAIMessageStore();
521
+ const messagesSignal = signal([]);
522
+ const isStreamingSignal = signal(false);
523
+ const errorSignal = signal(null);
524
+ const activeConversationIdSignal = signal(conversationId ?? null);
525
+ const syncState = () => {
526
+ const snapshot = store.getSnapshot();
527
+ const convId = activeConversationIdSignal() ?? snapshot.activeConversationId;
528
+ const conversation = convId ? snapshot.conversations.get(convId) : undefined;
529
+ messagesSignal.set(conversation?.messages ?? []);
530
+ isStreamingSignal.set(snapshot.isStreaming);
531
+ errorSignal.set(snapshot.error);
532
+ if (convId) {
533
+ activeConversationIdSignal.set(convId);
534
+ }
535
+ };
536
+ const unsubscribeStore = store.subscribe(syncState);
537
+ const unsubscribeConnection = connection.subscribe((msg) => {
538
+ const action = serverMessageToAction(msg);
539
+ if (action) {
540
+ store.dispatch(action);
541
+ }
542
+ });
543
+ const entry = {
544
+ connection,
545
+ store,
546
+ unsubscribeConnection,
547
+ unsubscribeStore
548
+ };
549
+ this.connections.set(path, entry);
550
+ const send = (content) => {
551
+ const convId = activeConversationIdSignal() ?? generateId();
552
+ const msgId = generateId();
553
+ store.dispatch({
554
+ content,
555
+ conversationId: convId,
556
+ messageId: msgId,
557
+ type: "send"
558
+ });
559
+ connection.send({
560
+ content,
561
+ conversationId: convId,
562
+ type: "message"
563
+ });
564
+ };
565
+ const cancel = () => {
566
+ const convId = activeConversationIdSignal();
567
+ if (convId) {
568
+ store.dispatch({ type: "cancel" });
569
+ connection.send({ conversationId: convId, type: "cancel" });
570
+ }
571
+ };
572
+ const branch = (messageId, content) => {
573
+ const convId = activeConversationIdSignal();
574
+ if (convId) {
575
+ connection.send({
576
+ content,
577
+ conversationId: convId,
578
+ messageId,
579
+ type: "branch"
580
+ });
581
+ }
582
+ };
583
+ return {
584
+ branch,
585
+ cancel,
586
+ error: computed(() => errorSignal()),
587
+ isStreaming: computed(() => isStreamingSignal()),
588
+ messages: computed(() => messagesSignal()),
589
+ send
590
+ };
591
+ }
592
+ createHandle(entry, conversationId) {
593
+ const { connection, store } = entry;
594
+ const messagesSignal = signal([]);
595
+ const isStreamingSignal = signal(false);
596
+ const errorSignal = signal(null);
597
+ const activeConversationIdSignal = signal(conversationId ?? null);
598
+ store.subscribe(() => {
599
+ const snapshot = store.getSnapshot();
600
+ const convId = activeConversationIdSignal() ?? snapshot.activeConversationId;
601
+ const conversation = convId ? snapshot.conversations.get(convId) : undefined;
602
+ messagesSignal.set(conversation?.messages ?? []);
603
+ isStreamingSignal.set(snapshot.isStreaming);
604
+ errorSignal.set(snapshot.error);
605
+ if (convId) {
606
+ activeConversationIdSignal.set(convId);
607
+ }
608
+ });
609
+ const send = (content) => {
610
+ const convId = activeConversationIdSignal() ?? generateId();
611
+ const msgId = generateId();
612
+ store.dispatch({
613
+ content,
614
+ conversationId: convId,
615
+ messageId: msgId,
616
+ type: "send"
617
+ });
618
+ connection.send({
619
+ content,
620
+ conversationId: convId,
621
+ type: "message"
622
+ });
623
+ };
624
+ const cancel = () => {
625
+ const convId = activeConversationIdSignal();
626
+ if (convId) {
627
+ store.dispatch({ type: "cancel" });
628
+ connection.send({ conversationId: convId, type: "cancel" });
629
+ }
630
+ };
631
+ const branch = (messageId, content) => {
632
+ const convId = activeConversationIdSignal();
633
+ if (convId) {
634
+ connection.send({
635
+ content,
636
+ conversationId: convId,
637
+ messageId,
638
+ type: "branch"
639
+ });
640
+ }
641
+ };
642
+ return {
643
+ branch,
644
+ cancel,
645
+ error: computed(() => errorSignal()),
646
+ isStreaming: computed(() => isStreamingSignal()),
647
+ messages: computed(() => messagesSignal()),
648
+ send
649
+ };
650
+ }
651
+ ngOnDestroy() {
652
+ for (const [, entry] of this.connections) {
653
+ entry.unsubscribeConnection();
654
+ entry.unsubscribeStore();
655
+ entry.connection.close();
656
+ }
657
+ this.connections.clear();
658
+ }
659
+ }
660
+ AIStreamService = __legacyDecorateClassTS([
661
+ Injectable({ providedIn: "root" })
662
+ ], AIStreamService);
663
+ export {
664
+ AIStreamService
665
+ };
666
+
667
+ //# debugId=4CDC62785D76E1AD64756E2164756E21
668
+ //# sourceMappingURL=index.js.map