@mordn/chat-widget 0.1.1 → 0.1.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.
@@ -1,283 +1,10 @@
1
1
  import { UIMessage } from 'ai';
2
2
  import * as drizzle_orm_postgres_js from 'drizzle-orm/postgres-js';
3
3
  import postgres from 'postgres';
4
- import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
4
+ import { s as schema } from '../index-uiN6exzS.mjs';
5
+ export { C as Conversation, M as Message, N as NewConversation, a as NewMessage, c as conversations, m as messages } from '../index-uiN6exzS.mjs';
5
6
  import 'drizzle-orm';
6
-
7
- /**
8
- * Conversations table
9
- * Stores chat conversation metadata
10
- */
11
- declare const conversations: drizzle_orm_pg_core.PgTableWithColumns<{
12
- name: "conversations";
13
- schema: undefined;
14
- columns: {
15
- id: drizzle_orm_pg_core.PgColumn<{
16
- name: "id";
17
- tableName: "conversations";
18
- dataType: "string";
19
- columnType: "PgText";
20
- data: string;
21
- driverParam: string;
22
- notNull: true;
23
- hasDefault: false;
24
- isPrimaryKey: true;
25
- isAutoincrement: false;
26
- hasRuntimeDefault: false;
27
- enumValues: [string, ...string[]];
28
- baseColumn: never;
29
- identity: undefined;
30
- generated: undefined;
31
- }, {}, {}>;
32
- userId: drizzle_orm_pg_core.PgColumn<{
33
- name: "user_id";
34
- tableName: "conversations";
35
- dataType: "string";
36
- columnType: "PgText";
37
- data: string;
38
- driverParam: string;
39
- notNull: true;
40
- hasDefault: false;
41
- isPrimaryKey: false;
42
- isAutoincrement: false;
43
- hasRuntimeDefault: false;
44
- enumValues: [string, ...string[]];
45
- baseColumn: never;
46
- identity: undefined;
47
- generated: undefined;
48
- }, {}, {}>;
49
- title: drizzle_orm_pg_core.PgColumn<{
50
- name: "title";
51
- tableName: "conversations";
52
- dataType: "string";
53
- columnType: "PgText";
54
- data: string;
55
- driverParam: string;
56
- notNull: true;
57
- hasDefault: true;
58
- isPrimaryKey: false;
59
- isAutoincrement: false;
60
- hasRuntimeDefault: false;
61
- enumValues: [string, ...string[]];
62
- baseColumn: never;
63
- identity: undefined;
64
- generated: undefined;
65
- }, {}, {}>;
66
- metadata: drizzle_orm_pg_core.PgColumn<{
67
- name: "metadata";
68
- tableName: "conversations";
69
- dataType: "json";
70
- columnType: "PgJsonb";
71
- data: unknown;
72
- driverParam: unknown;
73
- notNull: false;
74
- hasDefault: false;
75
- isPrimaryKey: false;
76
- isAutoincrement: false;
77
- hasRuntimeDefault: false;
78
- enumValues: undefined;
79
- baseColumn: never;
80
- identity: undefined;
81
- generated: undefined;
82
- }, {}, {}>;
83
- createdAt: drizzle_orm_pg_core.PgColumn<{
84
- name: "created_at";
85
- tableName: "conversations";
86
- dataType: "date";
87
- columnType: "PgTimestamp";
88
- data: Date;
89
- driverParam: string;
90
- notNull: true;
91
- hasDefault: true;
92
- isPrimaryKey: false;
93
- isAutoincrement: false;
94
- hasRuntimeDefault: false;
95
- enumValues: undefined;
96
- baseColumn: never;
97
- identity: undefined;
98
- generated: undefined;
99
- }, {}, {}>;
100
- updatedAt: drizzle_orm_pg_core.PgColumn<{
101
- name: "updated_at";
102
- tableName: "conversations";
103
- dataType: "date";
104
- columnType: "PgTimestamp";
105
- data: Date;
106
- driverParam: string;
107
- notNull: true;
108
- hasDefault: true;
109
- isPrimaryKey: false;
110
- isAutoincrement: false;
111
- hasRuntimeDefault: false;
112
- enumValues: undefined;
113
- baseColumn: never;
114
- identity: undefined;
115
- generated: undefined;
116
- }, {}, {}>;
117
- };
118
- dialect: "pg";
119
- }>;
120
- /**
121
- * Messages table
122
- * Stores individual chat messages
123
- */
124
- declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
125
- name: "messages";
126
- schema: undefined;
127
- columns: {
128
- id: drizzle_orm_pg_core.PgColumn<{
129
- name: "id";
130
- tableName: "messages";
131
- dataType: "string";
132
- columnType: "PgText";
133
- data: string;
134
- driverParam: string;
135
- notNull: true;
136
- hasDefault: false;
137
- isPrimaryKey: true;
138
- isAutoincrement: false;
139
- hasRuntimeDefault: false;
140
- enumValues: [string, ...string[]];
141
- baseColumn: never;
142
- identity: undefined;
143
- generated: undefined;
144
- }, {}, {}>;
145
- conversationId: drizzle_orm_pg_core.PgColumn<{
146
- name: "conversation_id";
147
- tableName: "messages";
148
- dataType: "string";
149
- columnType: "PgText";
150
- data: string;
151
- driverParam: string;
152
- notNull: true;
153
- hasDefault: false;
154
- isPrimaryKey: false;
155
- isAutoincrement: false;
156
- hasRuntimeDefault: false;
157
- enumValues: [string, ...string[]];
158
- baseColumn: never;
159
- identity: undefined;
160
- generated: undefined;
161
- }, {}, {}>;
162
- role: drizzle_orm_pg_core.PgColumn<{
163
- name: "role";
164
- tableName: "messages";
165
- dataType: "string";
166
- columnType: "PgText";
167
- data: string;
168
- driverParam: string;
169
- notNull: true;
170
- hasDefault: false;
171
- isPrimaryKey: false;
172
- isAutoincrement: false;
173
- hasRuntimeDefault: false;
174
- enumValues: [string, ...string[]];
175
- baseColumn: never;
176
- identity: undefined;
177
- generated: undefined;
178
- }, {}, {}>;
179
- content: drizzle_orm_pg_core.PgColumn<{
180
- name: "content";
181
- tableName: "messages";
182
- dataType: "string";
183
- columnType: "PgText";
184
- data: string;
185
- driverParam: string;
186
- notNull: true;
187
- hasDefault: false;
188
- isPrimaryKey: false;
189
- isAutoincrement: false;
190
- hasRuntimeDefault: false;
191
- enumValues: [string, ...string[]];
192
- baseColumn: never;
193
- identity: undefined;
194
- generated: undefined;
195
- }, {}, {}>;
196
- files: drizzle_orm_pg_core.PgColumn<{
197
- name: "files";
198
- tableName: "messages";
199
- dataType: "json";
200
- columnType: "PgJsonb";
201
- data: unknown;
202
- driverParam: unknown;
203
- notNull: false;
204
- hasDefault: false;
205
- isPrimaryKey: false;
206
- isAutoincrement: false;
207
- hasRuntimeDefault: false;
208
- enumValues: undefined;
209
- baseColumn: never;
210
- identity: undefined;
211
- generated: undefined;
212
- }, {}, {}>;
213
- model: drizzle_orm_pg_core.PgColumn<{
214
- name: "model";
215
- tableName: "messages";
216
- dataType: "string";
217
- columnType: "PgText";
218
- data: string;
219
- driverParam: string;
220
- notNull: false;
221
- hasDefault: false;
222
- isPrimaryKey: false;
223
- isAutoincrement: false;
224
- hasRuntimeDefault: false;
225
- enumValues: [string, ...string[]];
226
- baseColumn: never;
227
- identity: undefined;
228
- generated: undefined;
229
- }, {}, {}>;
230
- metadata: drizzle_orm_pg_core.PgColumn<{
231
- name: "metadata";
232
- tableName: "messages";
233
- dataType: "json";
234
- columnType: "PgJsonb";
235
- data: unknown;
236
- driverParam: unknown;
237
- notNull: false;
238
- hasDefault: false;
239
- isPrimaryKey: false;
240
- isAutoincrement: false;
241
- hasRuntimeDefault: false;
242
- enumValues: undefined;
243
- baseColumn: never;
244
- identity: undefined;
245
- generated: undefined;
246
- }, {}, {}>;
247
- createdAt: drizzle_orm_pg_core.PgColumn<{
248
- name: "created_at";
249
- tableName: "messages";
250
- dataType: "date";
251
- columnType: "PgTimestamp";
252
- data: Date;
253
- driverParam: string;
254
- notNull: true;
255
- hasDefault: true;
256
- isPrimaryKey: false;
257
- isAutoincrement: false;
258
- hasRuntimeDefault: false;
259
- enumValues: undefined;
260
- baseColumn: never;
261
- identity: undefined;
262
- generated: undefined;
263
- }, {}, {}>;
264
- };
265
- dialect: "pg";
266
- }>;
267
- type Conversation = typeof conversations.$inferSelect;
268
- type NewConversation = typeof conversations.$inferInsert;
269
- type Message = typeof messages.$inferSelect;
270
- type NewMessage = typeof messages.$inferInsert;
271
-
272
- type schema_Conversation = Conversation;
273
- type schema_Message = Message;
274
- type schema_NewConversation = NewConversation;
275
- type schema_NewMessage = NewMessage;
276
- declare const schema_conversations: typeof conversations;
277
- declare const schema_messages: typeof messages;
278
- declare namespace schema {
279
- export { type schema_Conversation as Conversation, type schema_Message as Message, type schema_NewConversation as NewConversation, type schema_NewMessage as NewMessage, schema_conversations as conversations, schema_messages as messages };
280
- }
7
+ import 'drizzle-orm/pg-core';
281
8
 
282
9
  /**
283
10
  * Create a new conversation
@@ -320,4 +47,4 @@ declare const db: drizzle_orm_postgres_js.PostgresJsDatabase<typeof schema> & {
320
47
  $client: postgres.Sql<{}>;
321
48
  };
322
49
 
323
- export { type Conversation, type Message, type NewConversation, type NewMessage, conversations, createChat, db, deleteConversation, getConversations, loadChat, messages, saveChat, updateConversationTitle };
50
+ export { createChat, db, deleteConversation, getConversations, loadChat, saveChat, updateConversationTitle };
@@ -1,283 +1,10 @@
1
1
  import { UIMessage } from 'ai';
2
2
  import * as drizzle_orm_postgres_js from 'drizzle-orm/postgres-js';
3
3
  import postgres from 'postgres';
4
- import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
4
+ import { s as schema } from '../index-uiN6exzS.js';
5
+ export { C as Conversation, M as Message, N as NewConversation, a as NewMessage, c as conversations, m as messages } from '../index-uiN6exzS.js';
5
6
  import 'drizzle-orm';
6
-
7
- /**
8
- * Conversations table
9
- * Stores chat conversation metadata
10
- */
11
- declare const conversations: drizzle_orm_pg_core.PgTableWithColumns<{
12
- name: "conversations";
13
- schema: undefined;
14
- columns: {
15
- id: drizzle_orm_pg_core.PgColumn<{
16
- name: "id";
17
- tableName: "conversations";
18
- dataType: "string";
19
- columnType: "PgText";
20
- data: string;
21
- driverParam: string;
22
- notNull: true;
23
- hasDefault: false;
24
- isPrimaryKey: true;
25
- isAutoincrement: false;
26
- hasRuntimeDefault: false;
27
- enumValues: [string, ...string[]];
28
- baseColumn: never;
29
- identity: undefined;
30
- generated: undefined;
31
- }, {}, {}>;
32
- userId: drizzle_orm_pg_core.PgColumn<{
33
- name: "user_id";
34
- tableName: "conversations";
35
- dataType: "string";
36
- columnType: "PgText";
37
- data: string;
38
- driverParam: string;
39
- notNull: true;
40
- hasDefault: false;
41
- isPrimaryKey: false;
42
- isAutoincrement: false;
43
- hasRuntimeDefault: false;
44
- enumValues: [string, ...string[]];
45
- baseColumn: never;
46
- identity: undefined;
47
- generated: undefined;
48
- }, {}, {}>;
49
- title: drizzle_orm_pg_core.PgColumn<{
50
- name: "title";
51
- tableName: "conversations";
52
- dataType: "string";
53
- columnType: "PgText";
54
- data: string;
55
- driverParam: string;
56
- notNull: true;
57
- hasDefault: true;
58
- isPrimaryKey: false;
59
- isAutoincrement: false;
60
- hasRuntimeDefault: false;
61
- enumValues: [string, ...string[]];
62
- baseColumn: never;
63
- identity: undefined;
64
- generated: undefined;
65
- }, {}, {}>;
66
- metadata: drizzle_orm_pg_core.PgColumn<{
67
- name: "metadata";
68
- tableName: "conversations";
69
- dataType: "json";
70
- columnType: "PgJsonb";
71
- data: unknown;
72
- driverParam: unknown;
73
- notNull: false;
74
- hasDefault: false;
75
- isPrimaryKey: false;
76
- isAutoincrement: false;
77
- hasRuntimeDefault: false;
78
- enumValues: undefined;
79
- baseColumn: never;
80
- identity: undefined;
81
- generated: undefined;
82
- }, {}, {}>;
83
- createdAt: drizzle_orm_pg_core.PgColumn<{
84
- name: "created_at";
85
- tableName: "conversations";
86
- dataType: "date";
87
- columnType: "PgTimestamp";
88
- data: Date;
89
- driverParam: string;
90
- notNull: true;
91
- hasDefault: true;
92
- isPrimaryKey: false;
93
- isAutoincrement: false;
94
- hasRuntimeDefault: false;
95
- enumValues: undefined;
96
- baseColumn: never;
97
- identity: undefined;
98
- generated: undefined;
99
- }, {}, {}>;
100
- updatedAt: drizzle_orm_pg_core.PgColumn<{
101
- name: "updated_at";
102
- tableName: "conversations";
103
- dataType: "date";
104
- columnType: "PgTimestamp";
105
- data: Date;
106
- driverParam: string;
107
- notNull: true;
108
- hasDefault: true;
109
- isPrimaryKey: false;
110
- isAutoincrement: false;
111
- hasRuntimeDefault: false;
112
- enumValues: undefined;
113
- baseColumn: never;
114
- identity: undefined;
115
- generated: undefined;
116
- }, {}, {}>;
117
- };
118
- dialect: "pg";
119
- }>;
120
- /**
121
- * Messages table
122
- * Stores individual chat messages
123
- */
124
- declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
125
- name: "messages";
126
- schema: undefined;
127
- columns: {
128
- id: drizzle_orm_pg_core.PgColumn<{
129
- name: "id";
130
- tableName: "messages";
131
- dataType: "string";
132
- columnType: "PgText";
133
- data: string;
134
- driverParam: string;
135
- notNull: true;
136
- hasDefault: false;
137
- isPrimaryKey: true;
138
- isAutoincrement: false;
139
- hasRuntimeDefault: false;
140
- enumValues: [string, ...string[]];
141
- baseColumn: never;
142
- identity: undefined;
143
- generated: undefined;
144
- }, {}, {}>;
145
- conversationId: drizzle_orm_pg_core.PgColumn<{
146
- name: "conversation_id";
147
- tableName: "messages";
148
- dataType: "string";
149
- columnType: "PgText";
150
- data: string;
151
- driverParam: string;
152
- notNull: true;
153
- hasDefault: false;
154
- isPrimaryKey: false;
155
- isAutoincrement: false;
156
- hasRuntimeDefault: false;
157
- enumValues: [string, ...string[]];
158
- baseColumn: never;
159
- identity: undefined;
160
- generated: undefined;
161
- }, {}, {}>;
162
- role: drizzle_orm_pg_core.PgColumn<{
163
- name: "role";
164
- tableName: "messages";
165
- dataType: "string";
166
- columnType: "PgText";
167
- data: string;
168
- driverParam: string;
169
- notNull: true;
170
- hasDefault: false;
171
- isPrimaryKey: false;
172
- isAutoincrement: false;
173
- hasRuntimeDefault: false;
174
- enumValues: [string, ...string[]];
175
- baseColumn: never;
176
- identity: undefined;
177
- generated: undefined;
178
- }, {}, {}>;
179
- content: drizzle_orm_pg_core.PgColumn<{
180
- name: "content";
181
- tableName: "messages";
182
- dataType: "string";
183
- columnType: "PgText";
184
- data: string;
185
- driverParam: string;
186
- notNull: true;
187
- hasDefault: false;
188
- isPrimaryKey: false;
189
- isAutoincrement: false;
190
- hasRuntimeDefault: false;
191
- enumValues: [string, ...string[]];
192
- baseColumn: never;
193
- identity: undefined;
194
- generated: undefined;
195
- }, {}, {}>;
196
- files: drizzle_orm_pg_core.PgColumn<{
197
- name: "files";
198
- tableName: "messages";
199
- dataType: "json";
200
- columnType: "PgJsonb";
201
- data: unknown;
202
- driverParam: unknown;
203
- notNull: false;
204
- hasDefault: false;
205
- isPrimaryKey: false;
206
- isAutoincrement: false;
207
- hasRuntimeDefault: false;
208
- enumValues: undefined;
209
- baseColumn: never;
210
- identity: undefined;
211
- generated: undefined;
212
- }, {}, {}>;
213
- model: drizzle_orm_pg_core.PgColumn<{
214
- name: "model";
215
- tableName: "messages";
216
- dataType: "string";
217
- columnType: "PgText";
218
- data: string;
219
- driverParam: string;
220
- notNull: false;
221
- hasDefault: false;
222
- isPrimaryKey: false;
223
- isAutoincrement: false;
224
- hasRuntimeDefault: false;
225
- enumValues: [string, ...string[]];
226
- baseColumn: never;
227
- identity: undefined;
228
- generated: undefined;
229
- }, {}, {}>;
230
- metadata: drizzle_orm_pg_core.PgColumn<{
231
- name: "metadata";
232
- tableName: "messages";
233
- dataType: "json";
234
- columnType: "PgJsonb";
235
- data: unknown;
236
- driverParam: unknown;
237
- notNull: false;
238
- hasDefault: false;
239
- isPrimaryKey: false;
240
- isAutoincrement: false;
241
- hasRuntimeDefault: false;
242
- enumValues: undefined;
243
- baseColumn: never;
244
- identity: undefined;
245
- generated: undefined;
246
- }, {}, {}>;
247
- createdAt: drizzle_orm_pg_core.PgColumn<{
248
- name: "created_at";
249
- tableName: "messages";
250
- dataType: "date";
251
- columnType: "PgTimestamp";
252
- data: Date;
253
- driverParam: string;
254
- notNull: true;
255
- hasDefault: true;
256
- isPrimaryKey: false;
257
- isAutoincrement: false;
258
- hasRuntimeDefault: false;
259
- enumValues: undefined;
260
- baseColumn: never;
261
- identity: undefined;
262
- generated: undefined;
263
- }, {}, {}>;
264
- };
265
- dialect: "pg";
266
- }>;
267
- type Conversation = typeof conversations.$inferSelect;
268
- type NewConversation = typeof conversations.$inferInsert;
269
- type Message = typeof messages.$inferSelect;
270
- type NewMessage = typeof messages.$inferInsert;
271
-
272
- type schema_Conversation = Conversation;
273
- type schema_Message = Message;
274
- type schema_NewConversation = NewConversation;
275
- type schema_NewMessage = NewMessage;
276
- declare const schema_conversations: typeof conversations;
277
- declare const schema_messages: typeof messages;
278
- declare namespace schema {
279
- export { type schema_Conversation as Conversation, type schema_Message as Message, type schema_NewConversation as NewConversation, type schema_NewMessage as NewMessage, schema_conversations as conversations, schema_messages as messages };
280
- }
7
+ import 'drizzle-orm/pg-core';
281
8
 
282
9
  /**
283
10
  * Create a new conversation
@@ -320,4 +47,4 @@ declare const db: drizzle_orm_postgres_js.PostgresJsDatabase<typeof schema> & {
320
47
  $client: postgres.Sql<{}>;
321
48
  };
322
49
 
323
- export { type Conversation, type Message, type NewConversation, type NewMessage, conversations, createChat, db, deleteConversation, getConversations, loadChat, messages, saveChat, updateConversationTitle };
50
+ export { createChat, db, deleteConversation, getConversations, loadChat, saveChat, updateConversationTitle };
package/dist/db/index.js CHANGED
@@ -161,8 +161,9 @@ async function saveChat({
161
161
  for (const msg of newMessages) {
162
162
  const textPart = msg.parts?.find((p) => p.type === "text");
163
163
  const fileParts = msg.parts?.filter((p) => p.type === "file") || [];
164
+ const messageId = msg.role === "assistant" ? (0, import_ai.generateId)() : msg.id;
164
165
  await db.insert(messages).values({
165
- id: msg.id,
166
+ id: messageId,
166
167
  conversationId: chatId,
167
168
  role: msg.role,
168
169
  content: textPart?.text || "",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/index.ts","../../src/db/schema.ts","../../src/db/chat-store.ts"],"sourcesContent":["import 'server-only';\nimport { drizzle } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport * as schema from './schema';\n\n// Create postgres connection\nconst connectionString = process.env.DATABASE_URL!;\n\n// Disable prefetch as it is not supported for \"Transaction\" pool mode\nconst client = postgres(connectionString, { prepare: false });\n\n// Create drizzle database instance\nexport const db = drizzle(client, { schema });\n\n// Export schema for convenience\nexport * from './schema';\n\n// Export chat store functions\nexport * from './chat-store';\n","import { pgTable, text, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\n\n/**\n * Conversations table\n * Stores chat conversation metadata\n */\nexport const conversations = pgTable('conversations', {\n id: text('id').primaryKey(),\n userId: text('user_id').notNull(),\n title: text('title').notNull().default('New Chat'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at').defaultNow().notNull(),\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n}, (table) => [\n index('conversations_user_id_idx').on(table.userId),\n index('conversations_updated_at_idx').on(table.updatedAt),\n]);\n\n/**\n * Messages table\n * Stores individual chat messages\n */\nexport const messages = pgTable('messages', {\n id: text('id').primaryKey(),\n conversationId: text('conversation_id').notNull().references(() => conversations.id, { onDelete: 'cascade' }),\n role: text('role').notNull(), // 'user' | 'assistant' | 'system'\n content: text('content').notNull(),\n files: jsonb('files'), // Array of file attachments\n model: text('model'), // AI model used\n metadata: jsonb('metadata'), // Additional data (parts, reasoning, etc.)\n createdAt: timestamp('created_at').defaultNow().notNull(),\n}, (table) => [\n index('messages_conversation_id_idx').on(table.conversationId),\n index('messages_created_at_idx').on(table.createdAt),\n]);\n\n// Type exports for use in application code\nexport type Conversation = typeof conversations.$inferSelect;\nexport type NewConversation = typeof conversations.$inferInsert;\nexport type Message = typeof messages.$inferSelect;\nexport type NewMessage = typeof messages.$inferInsert;\n","import { generateId, UIMessage } from 'ai';\nimport { db, conversations, messages } from './index';\nimport { eq, desc, asc, sql } from 'drizzle-orm';\n\n/**\n * Create a new conversation\n */\nexport async function createChat(userId: string): Promise<string> {\n const id = generateId();\n\n await db.insert(conversations).values({\n id,\n userId,\n title: 'New Chat',\n metadata: {},\n });\n\n return id;\n}\n\n/**\n * Load messages for a conversation\n */\nexport async function loadChat(conversationId: string): Promise<UIMessage[]> {\n try {\n const dbMessages = await db\n .select()\n .from(messages)\n .where(eq(messages.conversationId, conversationId))\n .orderBy(asc(messages.createdAt));\n\n if (!dbMessages.length) return [];\n\n // Convert database messages to UIMessage format\n return dbMessages.map((msg) => {\n // If we have metadata with parts, use those (includes reasoning)\n const metadata = msg.metadata as { parts?: any[] } | null;\n if (metadata?.parts && Array.isArray(metadata.parts)) {\n return {\n id: msg.id,\n role: msg.role as 'user' | 'assistant' | 'system',\n parts: metadata.parts,\n createdAt: msg.createdAt,\n };\n }\n\n // Fallback to simple text message\n return {\n id: msg.id,\n role: msg.role as 'user' | 'assistant' | 'system',\n parts: [{ type: 'text', text: msg.content }],\n createdAt: msg.createdAt,\n };\n });\n } catch (error) {\n console.error('Error loading chat:', error);\n return [];\n }\n}\n\n/**\n * Update conversation title\n */\nexport async function updateConversationTitle(\n chatId: string,\n title: string\n): Promise<void> {\n try {\n await db\n .update(conversations)\n .set({ title, updatedAt: new Date() })\n .where(eq(conversations.id, chatId));\n } catch (error) {\n console.error('Error updating conversation title:', error);\n }\n}\n\n/**\n * Save messages to a conversation\n */\nexport async function saveChat({\n chatId,\n messages: chatMessages,\n model,\n userId,\n}: {\n chatId: string;\n messages: UIMessage[];\n model?: string;\n userId: string;\n}): Promise<void> {\n if (!userId) {\n console.error('userId is required for saveChat');\n return;\n }\n\n try {\n // Verify conversation exists\n const existingConv = await db\n .select({ id: conversations.id, title: conversations.title })\n .from(conversations)\n .where(eq(conversations.id, chatId))\n .limit(1);\n\n if (!existingConv.length) {\n console.error('Conversation not found:', chatId);\n return;\n }\n\n const conv = existingConv[0];\n\n // Update title if this is the first user message and title is still \"New Chat\"\n if (conv.title === 'New Chat') {\n const firstUserMessage = chatMessages.find((m) => m.role === 'user');\n if (firstUserMessage) {\n const textPart = firstUserMessage.parts?.find((p) => p.type === 'text') as { text: string } | undefined;\n if (textPart?.text) {\n const newTitle = textPart.text.slice(0, 100);\n await updateConversationTitle(chatId, newTitle);\n }\n }\n }\n\n // Get existing message IDs from database\n const existingMessages = await db\n .select({ id: messages.id })\n .from(messages)\n .where(eq(messages.conversationId, chatId));\n\n const existingIds = new Set(existingMessages.map((m) => m.id));\n\n // Insert only new messages\n const newMessages = chatMessages.filter((msg) => !existingIds.has(msg.id));\n\n if (newMessages.length > 0) {\n for (const msg of newMessages) {\n const textPart = msg.parts?.find((p) => p.type === 'text') as { text: string } | undefined;\n const fileParts = msg.parts?.filter((p) => p.type === 'file') || [];\n\n await db.insert(messages).values({\n id: msg.id,\n conversationId: chatId,\n role: msg.role,\n content: textPart?.text || '',\n files: fileParts,\n model: model || 'openai/gpt-4o-mini',\n metadata: { parts: msg.parts || [] },\n });\n }\n\n // Update conversation's updatedAt\n await db\n .update(conversations)\n .set({ updatedAt: new Date() })\n .where(eq(conversations.id, chatId));\n }\n } catch (error) {\n console.error('Error saving chat:', error);\n }\n}\n\n/**\n * Get all conversations for a user\n */\nexport async function getConversations(userId: string) {\n try {\n const result = await db\n .select({\n id: conversations.id,\n title: conversations.title,\n createdAt: conversations.createdAt,\n updatedAt: conversations.updatedAt,\n metadata: conversations.metadata,\n messageCount: sql<number>`(\n SELECT COUNT(*) FROM ${messages}\n WHERE ${messages.conversationId} = ${conversations.id}\n )`,\n })\n .from(conversations)\n .where(eq(conversations.userId, userId))\n .orderBy(desc(conversations.updatedAt));\n\n return result;\n } catch (error) {\n console.error('Error getting conversations:', error);\n return [];\n }\n}\n\n/**\n * Delete a conversation and all its messages\n */\nexport async function deleteConversation(chatId: string): Promise<void> {\n try {\n // Messages are deleted automatically due to cascade\n await db.delete(conversations).where(eq(conversations.id, chatId));\n } catch (error) {\n console.error('Error deleting conversation:', error);\n }\n}\n"],"mappings":"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","names":["postgres"]}
1
+ {"version":3,"sources":["../../src/db/index.ts","../../src/db/schema.ts","../../src/db/chat-store.ts"],"sourcesContent":["import 'server-only';\nimport { drizzle } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport * as schema from './schema';\n\n// Create postgres connection\nconst connectionString = process.env.DATABASE_URL!;\n\n// Disable prefetch as it is not supported for \"Transaction\" pool mode\nconst client = postgres(connectionString, { prepare: false });\n\n// Create drizzle database instance\nexport const db = drizzle(client, { schema });\n\n// Export schema for convenience\nexport * from './schema';\n\n// Export chat store functions\nexport * from './chat-store';\n","import { pgTable, text, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\n\n/**\n * Conversations table\n * Stores chat conversation metadata\n */\nexport const conversations = pgTable('conversations', {\n id: text('id').primaryKey(),\n userId: text('user_id').notNull(),\n title: text('title').notNull().default('New Chat'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at').defaultNow().notNull(),\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n}, (table) => [\n index('conversations_user_id_idx').on(table.userId),\n index('conversations_updated_at_idx').on(table.updatedAt),\n]);\n\n/**\n * Messages table\n * Stores individual chat messages\n */\nexport const messages = pgTable('messages', {\n id: text('id').primaryKey(),\n conversationId: text('conversation_id').notNull().references(() => conversations.id, { onDelete: 'cascade' }),\n role: text('role').notNull(), // 'user' | 'assistant' | 'system'\n content: text('content').notNull(),\n files: jsonb('files'), // Array of file attachments\n model: text('model'), // AI model used\n metadata: jsonb('metadata'), // Additional data (parts, reasoning, etc.)\n createdAt: timestamp('created_at').defaultNow().notNull(),\n}, (table) => [\n index('messages_conversation_id_idx').on(table.conversationId),\n index('messages_created_at_idx').on(table.createdAt),\n]);\n\n// Type exports for use in application code\nexport type Conversation = typeof conversations.$inferSelect;\nexport type NewConversation = typeof conversations.$inferInsert;\nexport type Message = typeof messages.$inferSelect;\nexport type NewMessage = typeof messages.$inferInsert;\n","import { generateId, UIMessage } from 'ai';\nimport { db, conversations, messages } from './index';\nimport { eq, desc, asc, sql } from 'drizzle-orm';\n\n/**\n * Create a new conversation\n */\nexport async function createChat(userId: string): Promise<string> {\n const id = generateId();\n\n await db.insert(conversations).values({\n id,\n userId,\n title: 'New Chat',\n metadata: {},\n });\n\n return id;\n}\n\n/**\n * Load messages for a conversation\n */\nexport async function loadChat(conversationId: string): Promise<UIMessage[]> {\n try {\n const dbMessages = await db\n .select()\n .from(messages)\n .where(eq(messages.conversationId, conversationId))\n .orderBy(asc(messages.createdAt));\n\n if (!dbMessages.length) return [];\n\n // Convert database messages to UIMessage format\n return dbMessages.map((msg) => {\n // If we have metadata with parts, use those (includes reasoning)\n const metadata = msg.metadata as { parts?: any[] } | null;\n if (metadata?.parts && Array.isArray(metadata.parts)) {\n return {\n id: msg.id,\n role: msg.role as 'user' | 'assistant' | 'system',\n parts: metadata.parts,\n createdAt: msg.createdAt,\n };\n }\n\n // Fallback to simple text message\n return {\n id: msg.id,\n role: msg.role as 'user' | 'assistant' | 'system',\n parts: [{ type: 'text', text: msg.content }],\n createdAt: msg.createdAt,\n };\n });\n } catch (error) {\n console.error('Error loading chat:', error);\n return [];\n }\n}\n\n/**\n * Update conversation title\n */\nexport async function updateConversationTitle(\n chatId: string,\n title: string\n): Promise<void> {\n try {\n await db\n .update(conversations)\n .set({ title, updatedAt: new Date() })\n .where(eq(conversations.id, chatId));\n } catch (error) {\n console.error('Error updating conversation title:', error);\n }\n}\n\n/**\n * Save messages to a conversation\n */\nexport async function saveChat({\n chatId,\n messages: chatMessages,\n model,\n userId,\n}: {\n chatId: string;\n messages: UIMessage[];\n model?: string;\n userId: string;\n}): Promise<void> {\n if (!userId) {\n console.error('userId is required for saveChat');\n return;\n }\n\n try {\n // Verify conversation exists\n const existingConv = await db\n .select({ id: conversations.id, title: conversations.title })\n .from(conversations)\n .where(eq(conversations.id, chatId))\n .limit(1);\n\n if (!existingConv.length) {\n console.error('Conversation not found:', chatId);\n return;\n }\n\n const conv = existingConv[0];\n\n // Update title if this is the first user message and title is still \"New Chat\"\n if (conv.title === 'New Chat') {\n const firstUserMessage = chatMessages.find((m) => m.role === 'user');\n if (firstUserMessage) {\n const textPart = firstUserMessage.parts?.find((p) => p.type === 'text') as { text: string } | undefined;\n if (textPart?.text) {\n const newTitle = textPart.text.slice(0, 100);\n await updateConversationTitle(chatId, newTitle);\n }\n }\n }\n\n // Get existing message IDs from database\n const existingMessages = await db\n .select({ id: messages.id })\n .from(messages)\n .where(eq(messages.conversationId, chatId));\n\n const existingIds = new Set(existingMessages.map((m) => m.id));\n\n // Insert only new messages\n const newMessages = chatMessages.filter((msg) => !existingIds.has(msg.id));\n\n if (newMessages.length > 0) {\n for (const msg of newMessages) {\n const textPart = msg.parts?.find((p) => p.type === 'text') as { text: string } | undefined;\n const fileParts = msg.parts?.filter((p) => p.type === 'file') || [];\n\n // Generate ID for assistant messages, use existing ID for user messages\n const messageId = msg.role === 'assistant' ? generateId() : msg.id;\n\n await db.insert(messages).values({\n id: messageId,\n conversationId: chatId,\n role: msg.role,\n content: textPart?.text || '',\n files: fileParts,\n model: model || 'openai/gpt-4o-mini',\n metadata: { parts: msg.parts || [] },\n });\n }\n\n // Update conversation's updatedAt\n await db\n .update(conversations)\n .set({ updatedAt: new Date() })\n .where(eq(conversations.id, chatId));\n }\n } catch (error) {\n console.error('Error saving chat:', error);\n }\n}\n\n/**\n * Get all conversations for a user\n */\nexport async function getConversations(userId: string) {\n try {\n const result = await db\n .select({\n id: conversations.id,\n title: conversations.title,\n createdAt: conversations.createdAt,\n updatedAt: conversations.updatedAt,\n metadata: conversations.metadata,\n messageCount: sql<number>`(\n SELECT COUNT(*) FROM ${messages}\n WHERE ${messages.conversationId} = ${conversations.id}\n )`,\n })\n .from(conversations)\n .where(eq(conversations.userId, userId))\n .orderBy(desc(conversations.updatedAt));\n\n return result;\n } catch (error) {\n console.error('Error getting conversations:', error);\n return [];\n }\n}\n\n/**\n * Delete a conversation and all its messages\n */\nexport async function deleteConversation(chatId: string): Promise<void> {\n try {\n // Messages are deleted automatically due to cascade\n await db.delete(conversations).where(eq(conversations.id, chatId));\n } catch (error) {\n console.error('Error deleting conversation:', error);\n }\n}\n"],"mappings":"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","names":["postgres"]}
package/dist/db/index.mjs CHANGED
@@ -125,8 +125,9 @@ async function saveChat({
125
125
  for (const msg of newMessages) {
126
126
  const textPart = msg.parts?.find((p) => p.type === "text");
127
127
  const fileParts = msg.parts?.filter((p) => p.type === "file") || [];
128
+ const messageId = msg.role === "assistant" ? generateId() : msg.id;
128
129
  await db.insert(messages).values({
129
- id: msg.id,
130
+ id: messageId,
130
131
  conversationId: chatId,
131
132
  role: msg.role,
132
133
  content: textPart?.text || "",