mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-10 20:35:17 +02:00
refactor: rename Electric hooks and clean consumer components
Rename hooks to remove Electric branding: - use-connectors-electric → use-connectors-sync (useConnectorsSync) - use-messages-electric → use-messages-sync (useMessagesSync) - use-comments-electric → use-comments-sync (useCommentsSync) Clean all Electric/PGlite references in consumer components: connector-popup.tsx, thread.tsx, page.tsx, use-indexing-connectors.ts, use-connector-dialog.ts
This commit is contained in:
parent
a02bc54e40
commit
f04ab89418
8 changed files with 32 additions and 43 deletions
|
|
@ -61,7 +61,7 @@ import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
|
|||
import { RecallMemoryToolUI, SaveMemoryToolUI } from "@/components/tool-ui/user-memory";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { useChatSessionStateSync } from "@/hooks/use-chat-session-state";
|
||||
import { useMessagesElectric } from "@/hooks/use-messages-electric";
|
||||
import { useMessagesSync } from "@/hooks/use-messages-sync";
|
||||
import { documentsApiService } from "@/lib/apis/documents-api.service";
|
||||
// import { WriteTodosToolUI } from "@/components/tool-ui/write-todos";
|
||||
import { getBearerToken } from "@/lib/auth-utils";
|
||||
|
|
@ -204,13 +204,13 @@ export default function NewChatPage() {
|
|||
// Get current user for author info in shared chats
|
||||
const { data: currentUser } = useAtomValue(currentUserAtom);
|
||||
|
||||
// Live collaboration: sync session state and messages via Electric SQL
|
||||
// Live collaboration: sync session state and messages via Zero
|
||||
useChatSessionStateSync(threadId);
|
||||
const { data: membersData } = useAtomValue(membersAtom);
|
||||
|
||||
const handleElectricMessagesUpdate = useCallback(
|
||||
const handleSyncedMessagesUpdate = useCallback(
|
||||
(
|
||||
electricMessages: {
|
||||
syncedMessages: {
|
||||
id: number;
|
||||
thread_id: number;
|
||||
role: string;
|
||||
|
|
@ -224,11 +224,11 @@ export default function NewChatPage() {
|
|||
}
|
||||
|
||||
setMessages((prev) => {
|
||||
if (electricMessages.length < prev.length) {
|
||||
if (syncedMessages.length < prev.length) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
return electricMessages.map((msg) => {
|
||||
return syncedMessages.map((msg) => {
|
||||
const member = msg.author_id
|
||||
? membersData?.find((m) => m.user_id === msg.author_id)
|
||||
: null;
|
||||
|
|
@ -255,7 +255,7 @@ export default function NewChatPage() {
|
|||
[isRunning, membersData]
|
||||
);
|
||||
|
||||
useMessagesElectric(threadId, handleElectricMessagesUpdate);
|
||||
useMessagesSync(threadId, handleSyncedMessagesUpdate);
|
||||
|
||||
// Extract search_space_id from URL params
|
||||
const searchSpaceId = useMemo(() => {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
|||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { Tabs, TabsContent } from "@/components/ui/tabs";
|
||||
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
||||
import { useConnectorsElectric } from "@/hooks/use-connectors-electric";
|
||||
import { useConnectorsSync } from "@/hooks/use-connectors-sync";
|
||||
import { PICKER_CLOSE_EVENT, PICKER_OPEN_EVENT } from "@/hooks/use-google-picker";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ConnectorDialogHeader } from "./connector-popup/components/connector-dialog-header";
|
||||
|
|
@ -157,33 +157,24 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
};
|
||||
}, []);
|
||||
|
||||
// Fetch connectors using Electric SQL + PGlite for real-time updates
|
||||
// This provides instant updates when connectors change, without polling
|
||||
const {
|
||||
connectors: connectorsFromElectric = [],
|
||||
connectors: connectorsFromSync = [],
|
||||
loading: connectorsLoading,
|
||||
error: connectorsError,
|
||||
refreshConnectors: refreshConnectorsElectric,
|
||||
} = useConnectorsElectric(searchSpaceId);
|
||||
refreshConnectors: refreshConnectorsSync,
|
||||
} = useConnectorsSync(searchSpaceId);
|
||||
|
||||
// Fallback to API if Electric is not available or fails
|
||||
// Use Electric data if: 1) we have data, or 2) still loading without error
|
||||
// Use API data if: Electric failed (has error) or finished loading with no data
|
||||
const useElectricData =
|
||||
connectorsFromElectric.length > 0 || (connectorsLoading && !connectorsError);
|
||||
const connectors = useElectricData ? connectorsFromElectric : allConnectors || [];
|
||||
const useSyncData =
|
||||
connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
|
||||
const connectors = useSyncData ? connectorsFromSync : allConnectors || [];
|
||||
|
||||
// Manual refresh function that works with both Electric and API
|
||||
const refreshConnectors = async () => {
|
||||
if (useElectricData) {
|
||||
await refreshConnectorsElectric();
|
||||
} else {
|
||||
// Fallback: use allConnectors from useConnectorDialog (which uses connectorsAtom)
|
||||
// The connectorsAtom will handle refetching if needed
|
||||
if (useSyncData) {
|
||||
await refreshConnectorsSync();
|
||||
}
|
||||
};
|
||||
|
||||
// Track indexing state locally - clears automatically when Electric SQL detects last_indexed_at changed
|
||||
// Track indexing state locally - clears automatically when last_indexed_at changes via real-time sync
|
||||
// Also clears when failed notifications are detected
|
||||
const { indexingConnectorIds, startIndexing, stopIndexing } = useIndexingConnectors(
|
||||
connectors as SearchSourceConnector[],
|
||||
|
|
@ -204,7 +195,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
const activeConnectorsCount = connectors.length;
|
||||
|
||||
// Check which connectors are already connected
|
||||
// Using Electric SQL + PGlite for real-time connector updates
|
||||
// Real-time connector updates via Zero sync
|
||||
const connectedTypes = new Set<string>(
|
||||
(connectors || []).map((c: SearchSourceConnector) => c.connector_type)
|
||||
);
|
||||
|
|
@ -282,7 +273,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
<ConnectorAccountsListView
|
||||
connectorType={viewingAccountsType.connectorType}
|
||||
connectorTitle={viewingAccountsType.connectorTitle}
|
||||
connectors={(connectors || []) as SearchSourceConnector[]} // Using Electric SQL + PGlite for real-time connector updates (all connector types)
|
||||
connectors={(connectors || []) as SearchSourceConnector[]}
|
||||
indexingConnectorIds={indexingConnectorIds}
|
||||
onBack={handleBackFromAccountsList}
|
||||
onManage={handleStartEdit}
|
||||
|
|
@ -314,7 +305,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
...editingConnector,
|
||||
config: connectorConfig || editingConnector.config,
|
||||
name: editingConnector.name,
|
||||
// Sync last_indexed_at with live data from Electric SQL for real-time updates
|
||||
// Sync last_indexed_at with live data from real-time sync
|
||||
last_indexed_at:
|
||||
(connectors as SearchSourceConnector[]).find((c) => c.id === editingConnector.id)
|
||||
?.last_indexed_at ?? editingConnector.last_indexed_at,
|
||||
|
|
|
|||
|
|
@ -1569,7 +1569,7 @@ export const useConnectorDialog = () => {
|
|||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
});
|
||||
// Note: Don't call stopIndexing here - let useIndexingConnectors hook
|
||||
// detect when last_indexed_at changes via Electric SQL
|
||||
// detect when last_indexed_at changes via real-time sync
|
||||
} catch (error) {
|
||||
console.error("Error indexing connector content:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Failed to start indexing");
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ function isTaskTimedOut(startedAt: string | null | undefined): boolean {
|
|||
*
|
||||
* This provides a better UX than polling by:
|
||||
* 1. Setting indexing state immediately when user triggers indexing (optimistic)
|
||||
* 2. Detecting in_progress notifications from Electric SQL to restore state after remounts
|
||||
* 2. Detecting in_progress notifications to restore state after remounts
|
||||
* 3. Clearing indexing state when notifications become completed or failed
|
||||
* 4. Clearing indexing state when Electric SQL detects last_indexed_at changed
|
||||
* 4. Clearing indexing state when real-time sync detects last_indexed_at changed
|
||||
* 5. Detecting stale/stuck tasks that haven't updated in 15+ minutes
|
||||
* 6. Detecting hard timeout (8h) - tasks that definitely cannot still be running
|
||||
*
|
||||
* The actual `last_indexed_at` value comes from Electric SQL/PGlite, not local state.
|
||||
* The actual `last_indexed_at` value comes from real-time sync, not local state.
|
||||
*/
|
||||
export function useIndexingConnectors(
|
||||
connectors: SearchSourceConnector[],
|
||||
|
|
@ -66,7 +66,7 @@ export function useIndexingConnectors(
|
|||
// Track previous last_indexed_at values to detect changes
|
||||
const previousLastIndexedAtRef = useRef<Map<number, string | null>>(new Map());
|
||||
|
||||
// Detect when last_indexed_at changes (indexing completed) via Electric SQL
|
||||
// Detect when last_indexed_at changes (indexing completed) via real-time sync
|
||||
useEffect(() => {
|
||||
const previousValues = previousLastIndexedAtRef.current;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
|||
import { getToolIcon } from "@/contracts/enums/toolIcons";
|
||||
import type { Document } from "@/contracts/types/document.types";
|
||||
import { useBatchCommentsPreload } from "@/hooks/use-comments";
|
||||
import { useCommentsElectric } from "@/hooks/use-comments-electric";
|
||||
import { useCommentsSync } from "@/hooks/use-comments-sync";
|
||||
import { useMediaQuery } from "@/hooks/use-media-query";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
@ -365,8 +365,8 @@ const Composer: FC = () => {
|
|||
const respondingToUserId = sessionState?.respondingToUserId ?? null;
|
||||
const isBlockedByOtherUser = isAiResponding && respondingToUserId !== currentUser?.id;
|
||||
|
||||
// Sync comments for the entire thread via Electric SQL (one subscription per thread)
|
||||
useCommentsElectric(threadId);
|
||||
// Sync comments for the entire thread via Zero (one subscription per thread)
|
||||
useCommentsSync(threadId);
|
||||
|
||||
// Batch-prefetch comments for all assistant messages so individual useComments
|
||||
// hooks never fire their own network requests (eliminates N+1 API calls).
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ function transformComments(
|
|||
* Syncs ALL comments for a thread in ONE subscription, then updates
|
||||
* React Query cache for each message. This avoids N subscriptions for N messages.
|
||||
*/
|
||||
export function useCommentsElectric(threadId: number | null) {
|
||||
export function useCommentsSync(threadId: number | null) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: membersData } = useAtomValue(membersAtom);
|
||||
|
|
@ -9,7 +9,7 @@ import { useQuery } from "@rocicorp/zero/react";
|
|||
* Syncs connectors for a search space via Zero.
|
||||
* Returns connectors, loading state, error, and a refresh function.
|
||||
*/
|
||||
export function useConnectorsElectric(searchSpaceId: number | string | null) {
|
||||
export function useConnectorsSync(searchSpaceId: number | string | null) {
|
||||
const spaceId = searchSpaceId ? Number(searchSpaceId) : -1;
|
||||
|
||||
const [data, result] = useQuery(queries.connectors.bySpace({ searchSpaceId: spaceId }));
|
||||
|
|
@ -37,9 +37,7 @@ export function useConnectorsElectric(searchSpaceId: number | string | null) {
|
|||
const loading = !searchSpaceId ? false : result.type !== "complete";
|
||||
const error = !searchSpaceId ? null : null;
|
||||
|
||||
const refreshConnectors = async () => {
|
||||
// Zero handles reactivity automatically — no manual refresh needed
|
||||
};
|
||||
const refreshConnectors = async () => {};
|
||||
|
||||
return { connectors, loading, error, refreshConnectors };
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import { useQuery } from "@rocicorp/zero/react";
|
|||
* Syncs chat messages for a thread via Zero.
|
||||
* Calls onMessagesUpdate when messages change.
|
||||
*/
|
||||
export function useMessagesElectric(
|
||||
export function useMessagesSync(
|
||||
threadId: number | null,
|
||||
onMessagesUpdate: (messages: RawMessage[]) => void
|
||||
) {
|
||||
Loading…
Add table
Add a link
Reference in a new issue