Skip to content

Commit 28af51d

Browse files
fix: cannot use custom prompts (#295)
2 parents 1cba5d5 + 63c7fd4 commit 28af51d

File tree

3 files changed

+28
-57
lines changed

3 files changed

+28
-57
lines changed

src/App.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import '@/i18n'
22
import 'react-native-reanimated'
33

4-
import { DATABASE_NAME, db, expoDb } from '@db'
4+
import { db, expoDb } from '@db'
55
import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native'
66
import { useMigrations } from 'drizzle-orm/expo-sqlite/migrator'
77
import { useDrizzleStudio } from 'expo-drizzle-studio-plugin'
88
import { useFonts } from 'expo-font'
99
import * as SplashScreen from 'expo-splash-screen'
10-
import { SQLiteProvider } from 'expo-sqlite'
1110
import { HeroUINativeProvider } from 'heroui-native'
1211
import React, { Suspense, useEffect } from 'react'
1312
import { ActivityIndicator } from 'react-native'
@@ -138,11 +137,7 @@ export default function App() {
138137
return (
139138
<GestureHandlerRootView style={{ flex: 1 }}>
140139
<SafeAreaProvider>
141-
<Suspense fallback={<ActivityIndicator size="large" />}>
142-
<SQLiteProvider databaseName={DATABASE_NAME} options={{ enableChangeListener: true }} useSuspense>
143-
<AppWithRedux />
144-
</SQLiteProvider>
145-
</Suspense>
140+
<AppWithRedux />
146141
</SafeAreaProvider>
147142
</GestureHandlerRootView>
148143
)

src/componentsV2/features/Assistant/PromptTabContent.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { MotiView } from 'moti'
22
import React, { useEffect, useState } from 'react'
33
import { useTranslation } from 'react-i18next'
4+
import { Pressable } from 'react-native'
45
import { KeyboardAvoidingView } from 'react-native-keyboard-controller'
56

67
import TextField from '@/componentsV2/base/TextField'
@@ -69,7 +70,8 @@ export function PromptTabContent({ assistant, updateAssistant }: PromptTabConten
6970
<TextField.Label className="text-foreground-secondary text-sm font-medium">
7071
{t('common.prompt')}
7172
</TextField.Label>
72-
<TextField.Input
73+
<Pressable
74+
className="flex-1"
7375
onPress={() => {
7476
presentPromptDetailSheet(
7577
formData.prompt,
@@ -81,15 +83,18 @@ export function PromptTabContent({ assistant, updateAssistant }: PromptTabConten
8183
}
8284
}
8385
)
84-
}}
85-
editable={false}
86-
className="flex-1 rounded-lg px-3 py-3 text-sm"
87-
placeholder={t('common.prompt')}
88-
multiline
89-
numberOfLines={20}
90-
textAlignVertical="top"
91-
value={formData.prompt}
92-
/>
86+
}}>
87+
<TextField.Input
88+
editable={false}
89+
pointerEvents="none"
90+
className="flex-1 rounded-lg px-3 py-3 text-sm"
91+
placeholder={t('common.prompt')}
92+
multiline
93+
numberOfLines={20}
94+
textAlignVertical="top"
95+
value={formData.prompt}
96+
/>
97+
</Pressable>
9398
</TextField>
9499
</YStack>
95100
</KeyboardAvoidingView>

src/services/AssistantService.ts

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -602,18 +602,12 @@ export class AssistantService {
602602
}
603603

604604
/**
605-
* Perform optimistic assistant update with rollback on failure
605+
* Perform assistant update with database-first approach
606+
*
607+
* Sequence: Database Transaction → Cache Update → Notify Subscribers
608+
* This prevents race conditions with dual database connections
606609
*/
607610
private async performAssistantUpdate(assistantId: string, updates: Partial<Omit<Assistant, 'id'>>): Promise<void> {
608-
// Save old data for rollback
609-
const oldSystemAssistant = this.systemAssistantsCache.get(assistantId)
610-
? { ...this.systemAssistantsCache.get(assistantId)! }
611-
: null
612-
const oldLRUAssistant = this.assistantCache.get(assistantId) ? { ...this.assistantCache.get(assistantId)! } : null
613-
const oldAllAssistant = this.allAssistantsCache.get(assistantId)
614-
? { ...this.allAssistantsCache.get(assistantId)! }
615-
: null
616-
617611
try {
618612
// Fetch current assistant data
619613
let currentAssistantData: Assistant
@@ -639,44 +633,21 @@ export class AssistantService {
639633
id: assistantId
640634
}
641635

642-
// Optimistic update: update all caches
636+
// Persist to database FIRST (before any cache updates or notifications)
637+
await assistantDatabase.upsertAssistants([updatedAssistant])
638+
639+
// Update caches after successful database operation
643640
this.updateAssistantInCache(assistantId, updatedAssistant)
644641

645-
// Notify subscribers (UI updates immediately)
642+
// Notify subscribers after database and cache are in sync
646643
this.notifyAssistantSubscribers(assistantId)
647-
648-
// Persist to database
649-
await assistantDatabase.upsertAssistants([updatedAssistant])
650-
651-
// Notify other subscribers
652644
this.notifyGlobalSubscribers()
653645
this.notifyAllAssistantsSubscribers()
654646

655647
logger.debug(`Assistant updated successfully: ${assistantId}`)
656648
} catch (error) {
657-
// Rollback on failure
658-
logger.error('Failed to update assistant, rolling back:', error as Error)
659-
660-
if (oldSystemAssistant) {
661-
this.systemAssistantsCache.set(assistantId, oldSystemAssistant)
662-
} else {
663-
this.systemAssistantsCache.delete(assistantId)
664-
}
665-
666-
if (oldLRUAssistant) {
667-
this.assistantCache.set(assistantId, oldLRUAssistant)
668-
} else {
669-
this.assistantCache.delete(assistantId)
670-
}
671-
672-
if (oldAllAssistant) {
673-
this.allAssistantsCache.set(assistantId, oldAllAssistant)
674-
} else {
675-
this.allAssistantsCache.delete(assistantId)
676-
}
677-
678-
this.notifyAssistantSubscribers(assistantId)
679-
649+
// No rollback needed since we didn't update caches before transaction
650+
logger.error('Failed to update assistant:', error as Error)
680651
throw error
681652
}
682653
}

0 commit comments

Comments
 (0)