@tashiscool/vue 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # @llm-utils/vue
2
+
3
+ Vue 3 composables for LLM streaming. Reactive state management for chat interfaces.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @llm-utils/vue
9
+ # or
10
+ npm install @llm-utils/vue
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - **useStreaming** - Full streaming state management
16
+ - **useChunkBuffer** - Aggregate streaming chunks
17
+ - **useTypingIndicator** - Typing indicator state
18
+ - **useMessageHistory** - Persistent message history
19
+ - **SSE Support** - Parse Server-Sent Events
20
+ - **TypeScript** - Full type safety
21
+
22
+ ## Usage
23
+
24
+ ### Basic Streaming
25
+
26
+ ```vue
27
+ <script setup lang="ts">
28
+ import { useStreaming } from '@llm-utils/vue';
29
+
30
+ const { messages, status, send, isStreaming, abort } = useStreaming({
31
+ endpoint: '/api/chat',
32
+ onChunk: (chunk) => console.log('Received:', chunk),
33
+ });
34
+
35
+ async function handleSend(input: string) {
36
+ await send(input);
37
+ }
38
+ </script>
39
+
40
+ <template>
41
+ <div>
42
+ <div v-for="msg in messages" :key="msg.id">
43
+ <strong>{{ msg.role }}:</strong>
44
+ <span>{{ msg.content }}</span>
45
+ <span v-if="msg.isStreaming">▌</span>
46
+ </div>
47
+
48
+ <div v-if="status === 'connecting'">Connecting...</div>
49
+
50
+ <button @click="abort" v-if="isStreaming">Stop</button>
51
+ </div>
52
+ </template>
53
+ ```
54
+
55
+ ### Stream from URL
56
+
57
+ ```typescript
58
+ const { streamFrom, messages } = useStreaming();
59
+
60
+ // Stream from any URL
61
+ await streamFrom('/api/stream', {
62
+ method: 'POST',
63
+ body: JSON.stringify({ prompt: 'Hello' }),
64
+ });
65
+ ```
66
+
67
+ ### Chunk Buffer
68
+
69
+ ```typescript
70
+ import { useChunkBuffer } from '@llm-utils/vue';
71
+
72
+ const { content, append, flush } = useChunkBuffer();
73
+
74
+ // Append chunks
75
+ append('Hello ');
76
+ append('World');
77
+
78
+ console.log(content.value); // 'Hello World'
79
+ console.log(flush()); // 'Hello World' (also clears)
80
+ ```
81
+
82
+ ### Typing Indicator
83
+
84
+ ```typescript
85
+ import { useTypingIndicator } from '@llm-utils/vue';
86
+
87
+ const { isTyping, start, stop, startWithTimeout } = useTypingIndicator();
88
+
89
+ // Manual control
90
+ start();
91
+ // ... do work
92
+ stop();
93
+
94
+ // Auto-stop after 3 seconds
95
+ startWithTimeout(3000);
96
+ ```
97
+
98
+ ### Message History with Persistence
99
+
100
+ ```typescript
101
+ import { useMessageHistory } from '@llm-utils/vue';
102
+
103
+ const { messages, add, remove, clear } = useMessageHistory({
104
+ storageKey: 'my-chat-history',
105
+ maxMessages: 50,
106
+ });
107
+
108
+ // Add message
109
+ add({
110
+ role: 'user',
111
+ content: 'Hello!',
112
+ isStreaming: false,
113
+ });
114
+
115
+ // Messages persist across page reloads
116
+ ```
117
+
118
+ ## API Reference
119
+
120
+ ### useStreaming
121
+
122
+ ```typescript
123
+ interface UseStreamingReturn {
124
+ // State
125
+ status: Ref<StreamingStatus>;
126
+ messages: Ref<StreamingMessage[]>;
127
+ currentMessage: ComputedRef<StreamingMessage | null>;
128
+ isStreaming: ComputedRef<boolean>;
129
+ error: Ref<Error | null>;
130
+
131
+ // Actions
132
+ send: (content: string, options?) => Promise<void>;
133
+ streamFrom: (url: string, options?) => Promise<void>;
134
+ abort: () => void;
135
+ clear: () => void;
136
+ addMessage: (message) => void;
137
+ }
138
+ ```
139
+
140
+ ### StreamingMessage
141
+
142
+ ```typescript
143
+ interface StreamingMessage {
144
+ id: string;
145
+ role: 'user' | 'assistant' | 'system';
146
+ content: string;
147
+ isStreaming: boolean;
148
+ error?: string;
149
+ startedAt: Date;
150
+ completedAt?: Date;
151
+ }
152
+ ```
153
+
154
+ ### StreamingOptions
155
+
156
+ ```typescript
157
+ interface StreamingOptions {
158
+ endpoint?: string;
159
+ headers?: Record<string, string>;
160
+ transformChunk?: (chunk: string) => string;
161
+ onStart?: (message: StreamingMessage) => void;
162
+ onChunk?: (chunk: string, message: StreamingMessage) => void;
163
+ onComplete?: (message: StreamingMessage) => void;
164
+ onError?: (error: Error) => void;
165
+ }
166
+ ```
167
+
168
+ ## License
169
+
170
+ MIT
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @llm-utils/vue
3
+ * Vue 3 composables for LLM streaming
4
+ */
5
+ export { useStreaming, useChunkBuffer, useTypingIndicator, useMessageHistory, } from './useStreaming.js';
6
+ export type { StreamingStatus, StreamingMessage, StreamingOptions, StreamingState, StreamingActions, UseStreamingReturn, UseChunkBufferReturn, UseTypingIndicatorReturn, UseMessageHistoryOptions, UseMessageHistoryReturn, } from './useStreaming.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @llm-utils/vue
3
+ * Vue 3 composables for LLM streaming
4
+ */
5
+ export { useStreaming, useChunkBuffer, useTypingIndicator, useMessageHistory, } from './useStreaming.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Vue Streaming Composables
3
+ * Reactive state management for LLM streaming
4
+ */
5
+ import { type Ref, type ComputedRef } from 'vue';
6
+ /**
7
+ * Streaming status
8
+ */
9
+ export type StreamingStatus = 'idle' | 'connecting' | 'streaming' | 'complete' | 'error';
10
+ /**
11
+ * Streaming message
12
+ */
13
+ export interface StreamingMessage {
14
+ /** Unique message ID */
15
+ id: string;
16
+ /** Message role */
17
+ role: 'user' | 'assistant' | 'system';
18
+ /** Current content (incrementally updated) */
19
+ content: string;
20
+ /** Is message still streaming */
21
+ isStreaming: boolean;
22
+ /** Error if any */
23
+ error?: string;
24
+ /** Timestamp when started */
25
+ startedAt: Date;
26
+ /** Timestamp when completed */
27
+ completedAt?: Date;
28
+ }
29
+ /**
30
+ * Streaming options
31
+ */
32
+ export interface StreamingOptions {
33
+ /** API endpoint */
34
+ endpoint?: string;
35
+ /** Request headers */
36
+ headers?: Record<string, string>;
37
+ /** Transform response chunks */
38
+ transformChunk?: (chunk: string) => string;
39
+ /** On message start */
40
+ onStart?: (message: StreamingMessage) => void;
41
+ /** On chunk received */
42
+ onChunk?: (chunk: string, message: StreamingMessage) => void;
43
+ /** On message complete */
44
+ onComplete?: (message: StreamingMessage) => void;
45
+ /** On error */
46
+ onError?: (error: Error) => void;
47
+ }
48
+ /**
49
+ * Streaming state
50
+ */
51
+ export interface StreamingState {
52
+ /** Current status */
53
+ status: Ref<StreamingStatus>;
54
+ /** All messages */
55
+ messages: Ref<StreamingMessage[]>;
56
+ /** Current streaming message */
57
+ currentMessage: ComputedRef<StreamingMessage | null>;
58
+ /** Is currently streaming */
59
+ isStreaming: ComputedRef<boolean>;
60
+ /** Latest error */
61
+ error: Ref<Error | null>;
62
+ }
63
+ /**
64
+ * Streaming actions
65
+ */
66
+ export interface StreamingActions {
67
+ /** Send a message and stream response */
68
+ send: (content: string, options?: Partial<StreamingOptions>) => Promise<void>;
69
+ /** Stream from a URL */
70
+ streamFrom: (url: string, options?: RequestInit) => Promise<void>;
71
+ /** Abort current stream */
72
+ abort: () => void;
73
+ /** Clear all messages */
74
+ clear: () => void;
75
+ /** Add a message manually */
76
+ addMessage: (message: Omit<StreamingMessage, 'id' | 'startedAt'>) => void;
77
+ }
78
+ /**
79
+ * Use streaming composable return type
80
+ */
81
+ export interface UseStreamingReturn extends StreamingState, StreamingActions {
82
+ }
83
+ /**
84
+ * Vue composable for LLM streaming
85
+ */
86
+ export declare function useStreaming(defaultOptions?: StreamingOptions): UseStreamingReturn;
87
+ /**
88
+ * Chunk buffer composable for aggregating streaming chunks
89
+ */
90
+ export interface UseChunkBufferReturn {
91
+ /** Current buffered content */
92
+ content: Ref<string>;
93
+ /** Append a chunk */
94
+ append: (chunk: string) => void;
95
+ /** Clear buffer */
96
+ clear: () => void;
97
+ /** Get content and clear */
98
+ flush: () => string;
99
+ }
100
+ export declare function useChunkBuffer(): UseChunkBufferReturn;
101
+ /**
102
+ * Typing indicator composable
103
+ */
104
+ export interface UseTypingIndicatorReturn {
105
+ /** Is typing */
106
+ isTyping: Ref<boolean>;
107
+ /** Start typing */
108
+ start: () => void;
109
+ /** Stop typing */
110
+ stop: () => void;
111
+ /** Auto-stop after delay */
112
+ startWithTimeout: (ms: number) => void;
113
+ }
114
+ export declare function useTypingIndicator(): UseTypingIndicatorReturn;
115
+ /**
116
+ * Message history composable with persistence
117
+ */
118
+ export interface UseMessageHistoryOptions {
119
+ /** Storage key */
120
+ storageKey?: string;
121
+ /** Max messages to keep */
122
+ maxMessages?: number;
123
+ /** Use session storage instead of local */
124
+ sessionStorage?: boolean;
125
+ }
126
+ export interface UseMessageHistoryReturn {
127
+ /** Messages */
128
+ messages: Ref<StreamingMessage[]>;
129
+ /** Add message */
130
+ add: (message: Omit<StreamingMessage, 'id' | 'startedAt'>) => void;
131
+ /** Remove message */
132
+ remove: (id: string) => void;
133
+ /** Clear all */
134
+ clear: () => void;
135
+ /** Load from storage */
136
+ load: () => void;
137
+ /** Save to storage */
138
+ save: () => void;
139
+ }
140
+ export declare function useMessageHistory(options?: UseMessageHistoryOptions): UseMessageHistoryReturn;
141
+ //# sourceMappingURL=useStreaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStreaming.d.ts","sourceRoot":"","sources":["../src/useStreaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAE5E;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;IAChB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gCAAgC;IAChC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,uBAAuB;IACvB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,wBAAwB;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,0BAA0B;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACjD,eAAe;IACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,MAAM,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,mBAAmB;IACnB,QAAQ,EAAE,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAClC,gCAAgC;IAChC,cAAc,EAAE,WAAW,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,6BAA6B;IAC7B,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,mBAAmB;IACnB,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,wBAAwB;IACxB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,2BAA2B;IAC3B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yBAAyB;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,cAAc,EAAE,gBAAgB;CAAG;AAS/E;;GAEG;AACH,wBAAgB,YAAY,CAC1B,cAAc,GAAE,gBAAqB,GACpC,kBAAkB,CAmOpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+BAA+B;IAC/B,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,qBAAqB;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,mBAAmB;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,IAAI,oBAAoB,CAkBrD;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,gBAAgB;IAChB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,mBAAmB;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,kBAAkB;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,kBAAkB,IAAI,wBAAwB,CAsB7D;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe;IACf,QAAQ,EAAE,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAClC,kBAAkB;IAClB,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,CAAC;IACnE,qBAAqB;IACrB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,gBAAgB;IAChB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,wBAAwB;IACxB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,sBAAsB;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CAuEzB"}
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Vue Streaming Composables
3
+ * Reactive state management for LLM streaming
4
+ */
5
+ import { ref, computed } from 'vue';
6
+ /**
7
+ * Generate message ID
8
+ */
9
+ function generateId() {
10
+ return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
11
+ }
12
+ /**
13
+ * Vue composable for LLM streaming
14
+ */
15
+ export function useStreaming(defaultOptions = {}) {
16
+ // State
17
+ const status = ref('idle');
18
+ const messages = ref([]);
19
+ const error = ref(null);
20
+ let abortController = null;
21
+ // Computed
22
+ const currentMessage = computed(() => {
23
+ const streaming = messages.value.filter((m) => m.isStreaming);
24
+ return streaming.length > 0 ? streaming[streaming.length - 1] ?? null : null;
25
+ });
26
+ const isStreaming = computed(() => status.value === 'streaming');
27
+ /**
28
+ * Parse SSE data
29
+ */
30
+ function parseSSE(line) {
31
+ if (line.startsWith('data: ')) {
32
+ const data = line.slice(6);
33
+ if (data === '[DONE]')
34
+ return null;
35
+ try {
36
+ const parsed = JSON.parse(data);
37
+ // Handle various response formats
38
+ return (parsed.content ||
39
+ parsed.delta?.content ||
40
+ parsed.choices?.[0]?.delta?.content ||
41
+ parsed.text ||
42
+ '');
43
+ }
44
+ catch {
45
+ return data;
46
+ }
47
+ }
48
+ return null;
49
+ }
50
+ /**
51
+ * Stream from a URL
52
+ */
53
+ async function streamFrom(url, options = {}) {
54
+ abortController = new AbortController();
55
+ status.value = 'connecting';
56
+ error.value = null;
57
+ const message = {
58
+ id: generateId(),
59
+ role: 'assistant',
60
+ content: '',
61
+ isStreaming: true,
62
+ startedAt: new Date(),
63
+ };
64
+ messages.value.push(message);
65
+ defaultOptions.onStart?.(message);
66
+ try {
67
+ const response = await fetch(url, {
68
+ ...options,
69
+ signal: abortController.signal,
70
+ headers: {
71
+ ...defaultOptions.headers,
72
+ ...options.headers,
73
+ },
74
+ });
75
+ if (!response.ok) {
76
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
77
+ }
78
+ if (!response.body) {
79
+ throw new Error('Response body is null');
80
+ }
81
+ status.value = 'streaming';
82
+ const reader = response.body.getReader();
83
+ const decoder = new TextDecoder();
84
+ let buffer = '';
85
+ while (true) {
86
+ const { done, value } = await reader.read();
87
+ if (done)
88
+ break;
89
+ buffer += decoder.decode(value, { stream: true });
90
+ const lines = buffer.split('\n');
91
+ buffer = lines.pop() || '';
92
+ for (const line of lines) {
93
+ const trimmed = line.trim();
94
+ if (!trimmed)
95
+ continue;
96
+ let chunk = parseSSE(trimmed);
97
+ if (chunk === null)
98
+ continue;
99
+ if (defaultOptions.transformChunk) {
100
+ chunk = defaultOptions.transformChunk(chunk);
101
+ }
102
+ // Update message content
103
+ const msgIndex = messages.value.findIndex((m) => m.id === message.id);
104
+ if (msgIndex !== -1 && messages.value[msgIndex]) {
105
+ messages.value[msgIndex].content += chunk;
106
+ defaultOptions.onChunk?.(chunk, messages.value[msgIndex]);
107
+ }
108
+ }
109
+ }
110
+ // Complete message
111
+ const msgIndex = messages.value.findIndex((m) => m.id === message.id);
112
+ if (msgIndex !== -1 && messages.value[msgIndex]) {
113
+ messages.value[msgIndex].isStreaming = false;
114
+ messages.value[msgIndex].completedAt = new Date();
115
+ defaultOptions.onComplete?.(messages.value[msgIndex]);
116
+ }
117
+ status.value = 'complete';
118
+ }
119
+ catch (err) {
120
+ if (err.name === 'AbortError') {
121
+ status.value = 'idle';
122
+ return;
123
+ }
124
+ const errorObj = err instanceof Error ? err : new Error(String(err));
125
+ error.value = errorObj;
126
+ status.value = 'error';
127
+ // Mark message as error
128
+ const msgIndex = messages.value.findIndex((m) => m.id === message.id);
129
+ if (msgIndex !== -1 && messages.value[msgIndex]) {
130
+ messages.value[msgIndex].isStreaming = false;
131
+ messages.value[msgIndex].error = errorObj.message;
132
+ }
133
+ defaultOptions.onError?.(errorObj);
134
+ }
135
+ finally {
136
+ abortController = null;
137
+ }
138
+ }
139
+ /**
140
+ * Send a message and stream response
141
+ */
142
+ async function send(content, options = {}) {
143
+ const endpoint = options.endpoint || defaultOptions.endpoint;
144
+ if (!endpoint) {
145
+ throw new Error('No endpoint configured');
146
+ }
147
+ // Add user message
148
+ messages.value.push({
149
+ id: generateId(),
150
+ role: 'user',
151
+ content,
152
+ isStreaming: false,
153
+ startedAt: new Date(),
154
+ completedAt: new Date(),
155
+ });
156
+ // Stream response
157
+ await streamFrom(endpoint, {
158
+ method: 'POST',
159
+ headers: {
160
+ 'Content-Type': 'application/json',
161
+ ...defaultOptions.headers,
162
+ ...options.headers,
163
+ },
164
+ body: JSON.stringify({
165
+ messages: messages.value.map((m) => ({
166
+ role: m.role,
167
+ content: m.content,
168
+ })),
169
+ }),
170
+ });
171
+ }
172
+ /**
173
+ * Abort current stream
174
+ */
175
+ function abort() {
176
+ abortController?.abort();
177
+ status.value = 'idle';
178
+ }
179
+ /**
180
+ * Clear all messages
181
+ */
182
+ function clear() {
183
+ messages.value = [];
184
+ status.value = 'idle';
185
+ error.value = null;
186
+ }
187
+ /**
188
+ * Add message manually
189
+ */
190
+ function addMessage(msg) {
191
+ messages.value.push({
192
+ ...msg,
193
+ id: generateId(),
194
+ startedAt: new Date(),
195
+ });
196
+ }
197
+ return {
198
+ // State
199
+ status,
200
+ messages,
201
+ currentMessage,
202
+ isStreaming,
203
+ error,
204
+ // Actions
205
+ send,
206
+ streamFrom,
207
+ abort,
208
+ clear,
209
+ addMessage,
210
+ };
211
+ }
212
+ export function useChunkBuffer() {
213
+ const content = ref('');
214
+ function append(chunk) {
215
+ content.value += chunk;
216
+ }
217
+ function clear() {
218
+ content.value = '';
219
+ }
220
+ function flush() {
221
+ const result = content.value;
222
+ content.value = '';
223
+ return result;
224
+ }
225
+ return { content, append, clear, flush };
226
+ }
227
+ export function useTypingIndicator() {
228
+ const isTyping = ref(false);
229
+ let timeoutId = null;
230
+ function start() {
231
+ isTyping.value = true;
232
+ }
233
+ function stop() {
234
+ isTyping.value = false;
235
+ if (timeoutId) {
236
+ clearTimeout(timeoutId);
237
+ timeoutId = null;
238
+ }
239
+ }
240
+ function startWithTimeout(ms) {
241
+ start();
242
+ timeoutId = setTimeout(stop, ms);
243
+ }
244
+ return { isTyping, start, stop, startWithTimeout };
245
+ }
246
+ export function useMessageHistory(options = {}) {
247
+ const { storageKey = 'llm-utils-messages', maxMessages = 100, sessionStorage: useSession = false, } = options;
248
+ const messages = ref([]);
249
+ const storage = typeof window !== 'undefined'
250
+ ? useSession
251
+ ? window.sessionStorage
252
+ : window.localStorage
253
+ : null;
254
+ function add(msg) {
255
+ messages.value.push({
256
+ ...msg,
257
+ id: generateId(),
258
+ startedAt: new Date(),
259
+ });
260
+ // Trim if needed
261
+ if (messages.value.length > maxMessages) {
262
+ messages.value = messages.value.slice(-maxMessages);
263
+ }
264
+ save();
265
+ }
266
+ function remove(id) {
267
+ messages.value = messages.value.filter((m) => m.id !== id);
268
+ save();
269
+ }
270
+ function clear() {
271
+ messages.value = [];
272
+ save();
273
+ }
274
+ function load() {
275
+ if (!storage)
276
+ return;
277
+ try {
278
+ const stored = storage.getItem(storageKey);
279
+ if (stored) {
280
+ const parsed = JSON.parse(stored);
281
+ messages.value = parsed.map((m) => ({
282
+ ...m,
283
+ startedAt: new Date(m.startedAt),
284
+ completedAt: m.completedAt ? new Date(m.completedAt) : undefined,
285
+ }));
286
+ }
287
+ }
288
+ catch {
289
+ // Ignore parse errors
290
+ }
291
+ }
292
+ function save() {
293
+ if (!storage)
294
+ return;
295
+ try {
296
+ storage.setItem(storageKey, JSON.stringify(messages.value));
297
+ }
298
+ catch {
299
+ // Ignore storage errors
300
+ }
301
+ }
302
+ // Auto-load on init
303
+ load();
304
+ return { messages, add, remove, clear, load, save };
305
+ }
306
+ //# sourceMappingURL=useStreaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStreaming.js","sourceRoot":"","sources":["../src/useStreaming.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@tashiscool/vue",
3
+ "version": "0.1.0",
4
+ "description": "Vue 3 composables for LLM streaming",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest"
21
+ },
22
+ "keywords": [
23
+ "llm",
24
+ "ai",
25
+ "vue",
26
+ "vue3",
27
+ "composables",
28
+ "streaming",
29
+ "reactive"
30
+ ],
31
+ "license": "MIT",
32
+ "peerDependencies": {
33
+ "vue": "^3.3.0"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.4.0",
37
+ "vitest": "^1.6.0",
38
+ "vue": "^3.4.0"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/tashiscool/llm-utils.git",
43
+ "directory": "packages/vue"
44
+ }
45
+ }