Skip to content

Commit 8ee94a8

Browse files
author
Marvin Zhang
committed
feat: Enhance real-time event handling and update event types across the application
1 parent 658b67e commit 8ee94a8

File tree

14 files changed

+103
-71
lines changed

14 files changed

+103
-71
lines changed

Dockerfile.dev

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ RUN apk add --no-cache libc6-compat python3 make g++ curl
77
# Enable pnpm
88
ENV PNPM_HOME="/pnpm"
99
ENV PATH="$PNPM_HOME:$PATH"
10+
RUN npm install -g pnpm
1011

1112
# Set working directory
1213
WORKDIR /app

packages/ai/src/__tests__/services.test.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,12 @@
55
import { describe, it, expect, vi, beforeEach } from 'vitest';
66
import { DefaultChatImportService } from '../services/chat-import-service.js';
77
import { ChatHubService } from '../services/chat-hub-service.js';
8-
import type { StorageProvider } from '@codervisor/devlog-core';
9-
10-
// Mock storage provider
11-
const mockStorageProvider: StorageProvider = {
12-
saveChatSession: vi.fn(),
13-
saveChatMessages: vi.fn(),
14-
saveChatWorkspace: vi.fn(),
15-
} as any;
168

179
describe('DefaultChatImportService', () => {
1810
let service: DefaultChatImportService;
1911

2012
beforeEach(() => {
21-
service = new DefaultChatImportService(mockStorageProvider);
13+
service = new DefaultChatImportService();
2214
vi.clearAllMocks();
2315
});
2416

@@ -37,7 +29,7 @@ describe('ChatHubService', () => {
3729
let service: ChatHubService;
3830

3931
beforeEach(() => {
40-
service = new ChatHubService(mockStorageProvider);
32+
service = new ChatHubService();
4133
vi.clearAllMocks();
4234
});
4335

packages/ai/src/parsers/copilot/copilot-parser.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,4 @@ export class CopilotParser extends AIAssistantParser {
429429
);
430430
return workspaceData;
431431
}
432-
433-
// Legacy method name for backwards compatibility
434-
async discoverVSCodeCopilotData(): Promise<WorkspaceData> {
435-
return this.discoverChatData();
436-
}
437432
}

packages/cli/src/cli/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ program
138138
}
139139

140140
const parser = new CopilotParser();
141-
const projectData = await parser.discoverVSCodeCopilotData();
141+
const projectData = await parser.discoverChatData();
142142

143143
if (projectData.chat_sessions.length === 0) {
144144
spinner?.stop();

packages/web/app/api/projects/[id]/devlogs/[devlogId]/notes/[noteId]/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { NextRequest } from 'next/server';
22
import type { NoteCategory } from '@codervisor/devlog-core';
33
import { DevlogService, ProjectService } from '@codervisor/devlog-core';
4-
import { ApiErrors, createSuccessResponse, RouteParams, SSEEventType } from '@/lib';
4+
import { ApiErrors, createSuccessResponse, RouteParams } from '@/lib';
5+
import { RealtimeEventType } from '@/lib/realtime';
56
import { z } from 'zod';
67

78
// Mark this route as dynamic to prevent static generation
@@ -91,7 +92,7 @@ export async function PUT(
9192
category: updates.category as NoteCategory | undefined,
9293
});
9394

94-
return createSuccessResponse(updatedNote, { sseEventType: SSEEventType.DEVLOG_NOTE_UPDATED });
95+
return createSuccessResponse(updatedNote, { sseEventType: RealtimeEventType.DEVLOG_NOTE_UPDATED });
9596
} catch (error) {
9697
console.error('Error updating note:', error);
9798
if (error instanceof Error && error.message.includes('not found')) {
@@ -135,7 +136,7 @@ export async function DELETE(
135136
devlogId,
136137
noteId,
137138
},
138-
{ sseEventType: SSEEventType.DEVLOG_NOTE_DELETED },
139+
{ sseEventType: RealtimeEventType.DEVLOG_NOTE_DELETED },
139140
);
140141
} catch (error) {
141142
console.error('Error deleting note:', error);

packages/web/app/api/projects/[id]/devlogs/[devlogId]/notes/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { NextRequest } from 'next/server';
22
import type { NoteCategory } from '@codervisor/devlog-core';
33
import { DevlogService, ProjectService } from '@codervisor/devlog-core';
4-
import { ApiErrors, createSuccessResponse, RouteParams, SSEEventType } from '@/lib';
4+
import { ApiErrors, createSuccessResponse, RouteParams } from '@/lib';
5+
import { RealtimeEventType } from '@/lib/realtime';
56
import { DevlogAddNoteBodySchema, DevlogUpdateWithNoteBodySchema } from '@/schemas';
67

78
// Mark this route as dynamic to prevent static generation
@@ -107,7 +108,7 @@ export async function POST(
107108

108109
return createSuccessResponse(newNote, {
109110
status: 201,
110-
sseEventType: SSEEventType.DEVLOG_NOTE_CREATED,
111+
sseEventType: RealtimeEventType.DEVLOG_NOTE_CREATED,
111112
});
112113
} catch (error) {
113114
console.error('Error adding devlog note:', error);
@@ -172,7 +173,7 @@ export async function PUT(
172173

173174
// Return the updated entry with the note
174175
const finalEntry = await devlogService.get(devlogId, true); // Load with notes
175-
return createSuccessResponse(finalEntry, { sseEventType: SSEEventType.DEVLOG_UPDATED });
176+
return createSuccessResponse(finalEntry, { sseEventType: RealtimeEventType.DEVLOG_UPDATED });
176177
} catch (error) {
177178
console.error('Error updating devlog with note:', error);
178179
return ApiErrors.internalError('Failed to update devlog entry with note');

packages/web/app/api/projects/[id]/devlogs/[devlogId]/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NextRequest } from 'next/server';
22
import { DevlogService, ProjectService } from '@codervisor/devlog-core';
3-
import { ApiErrors, createSuccessResponse, SSEEventType, RouteParams } from '@/lib';
3+
import { ApiErrors, createSuccessResponse, RouteParams } from '@/lib';
4+
import { RealtimeEventType } from '@/lib/realtime';
45

56
// Mark this route as dynamic to prevent static generation
67
export const dynamic = 'force-dynamic';
@@ -94,7 +95,7 @@ export async function PUT(
9495
await devlogService.save(updatedEntry);
9596

9697
// Transform and return updated entry
97-
return createSuccessResponse(updatedEntry, { sseEventType: SSEEventType.DEVLOG_UPDATED });
98+
return createSuccessResponse(updatedEntry, { sseEventType: RealtimeEventType.DEVLOG_UPDATED });
9899
} catch (error) {
99100
console.error('Error updating devlog:', error);
100101
const message = error instanceof Error ? error.message : 'Failed to update devlog';
@@ -135,7 +136,7 @@ export async function DELETE(
135136

136137
return createSuccessResponse(
137138
{ deleted: true, devlogId },
138-
{ sseEventType: SSEEventType.DEVLOG_DELETED },
139+
{ sseEventType: RealtimeEventType.DEVLOG_DELETED },
139140
);
140141
} catch (error) {
141142
console.error('Error deleting devlog:', error);

packages/web/app/api/projects/[id]/devlogs/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import {
1616
createCollectionResponse,
1717
createSimpleCollectionResponse,
1818
createSuccessResponse,
19-
SSEEventType,
2019
} from '@/lib';
20+
import { RealtimeEventType } from '@/lib/realtime';
2121

2222
// Mark this route as dynamic to prevent static generation
2323
export const dynamic = 'force-dynamic';
@@ -144,7 +144,7 @@ export async function POST(request: NextRequest, { params }: { params: { id: str
144144
// Transform and return the actual saved devlog
145145
return createSuccessResponse(savedEntry, {
146146
status: 201,
147-
sseEventType: SSEEventType.DEVLOG_CREATED,
147+
sseEventType: RealtimeEventType.DEVLOG_CREATED,
148148
});
149149
} catch (error) {
150150
console.error('Error creating devlog:', error);

packages/web/app/api/projects/[id]/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
createSuccessResponse,
44
RouteParams,
55
ServiceHelper,
6-
SSEEventType,
6+
RealtimeEventType,
77
withErrorHandling,
88
} from '@/lib';
99
import { ApiValidator, UpdateProjectBodySchema } from '@/schemas';
@@ -62,7 +62,7 @@ export const PUT = withErrorHandling(
6262
// Update project
6363
const updatedProject = await projectResult.data.projectService.update(projectId, data);
6464

65-
return createSuccessResponse(updatedProject, { sseEventType: SSEEventType.PROJECT_UPDATED });
65+
return createSuccessResponse(updatedProject, { sseEventType: RealtimeEventType.PROJECT_UPDATED });
6666
},
6767
);
6868

@@ -88,7 +88,7 @@ export const DELETE = withErrorHandling(
8888

8989
return createSuccessResponse(
9090
{ deleted: true, projectId },
91-
{ sseEventType: SSEEventType.PROJECT_DELETED },
91+
{ sseEventType: RealtimeEventType.PROJECT_DELETED },
9292
);
9393
},
9494
);

packages/web/app/hooks/use-realtime.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,28 @@ export function useProjectEvents() {
8787
onProjectDeleted,
8888
};
8989
}
90+
91+
/**
92+
* Hook for subscribing to note events
93+
*/
94+
export function useNoteEvents() {
95+
const { subscribe } = useRealtime();
96+
97+
const onNoteCreated = useCallback((callback: (note: any) => void) => {
98+
return subscribe(RealtimeEventType.DEVLOG_NOTE_CREATED, callback);
99+
}, [subscribe]);
100+
101+
const onNoteUpdated = useCallback((callback: (note: any) => void) => {
102+
return subscribe(RealtimeEventType.DEVLOG_NOTE_UPDATED, callback);
103+
}, [subscribe]);
104+
105+
const onNoteDeleted = useCallback((callback: (data: { id: string }) => void) => {
106+
return subscribe(RealtimeEventType.DEVLOG_NOTE_DELETED, callback);
107+
}, [subscribe]);
108+
109+
return {
110+
onNoteCreated,
111+
onNoteUpdated,
112+
onNoteDeleted,
113+
};
114+
}

0 commit comments

Comments
 (0)