Skip to content

Commit

Permalink
Implemented Room Management
Browse files Browse the repository at this point in the history
  • Loading branch information
R1c4rdCo5t4 committed May 9, 2024
1 parent 9e76307 commit 78c91c5
Show file tree
Hide file tree
Showing 27 changed files with 243 additions and 115 deletions.
8 changes: 4 additions & 4 deletions code/server/src/ts/controllers/http/documentHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Request, Response } from 'express';
import { DocumentService } from '@controllers/ws/types';
import { DocumentService } from '@services/types';
import { httpResponse } from '@controllers/http/utils';

function documentHandlers(service: DocumentService) {
async function getDocuments(req: Request, res: Response) {
const documents = await service.getDocuments();
httpResponse.ok(res, documents);
// const documents = await service.getDocuments();
// httpResponse.ok(res, documents);
}

async function createDocument(req: Request, res: Response) {
const { title } = req.body;
const id = await service.createDocument(title);
const id = await service.createDocument(, title);
httpResponse.created(res, { id });
}

Expand Down
2 changes: 1 addition & 1 deletion code/server/src/ts/controllers/http/router.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express from 'express';
import PromiseRouter from 'express-promise-router';
import { DocumentService } from '@controllers/ws/types';
import { DocumentService } from '@services/types';
import documentHandlers from '@controllers/http/documentHandlers';
import errorHandler from '@controllers/http/errorHandler';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Socket } from 'socket.io';
import { InlineStyle } from '@notespace/shared/types/styles';
import { getRoomId } from '@controllers/ws/rooms';
import { getRoomId } from '@controllers/ws/rooms/roomOperations';

type CursorData = {
range: any;
Expand Down
4 changes: 2 additions & 2 deletions code/server/src/ts/controllers/ws/namespaces/document/join.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Socket } from 'socket.io';
import { joinRoom } from '@controllers/ws/rooms';
import rooms from '@controllers/ws/rooms/rooms';

function join() {
return function (socket: Socket, documentId: string) {
joinRoom(socket, documentId);
rooms.document.join(socket, documentId);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Socket } from 'socket.io';
import { leaveRoom } from '@controllers/ws/rooms';
import rooms from '@controllers/ws/rooms/rooms';

function leave() {
return function (socket: Socket) {
leaveRoom(socket);
rooms.document.leave(socket);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Socket } from 'socket.io';
import { DocumentService } from '@services//types';
import { Operation } from '@notespace/shared/crdt/types/operations';
import { getRoomId } from '@controllers/ws/rooms';
import { getRoomId } from '@controllers/ws/rooms/roomOperations';
import { ForbiddenError, InvalidParameterError } from '@domain/errors/errors';

function operation(service: DocumentService) {
Expand All @@ -12,7 +12,7 @@ function operation(service: DocumentService) {
if (!documentId) throw new ForbiddenError('Client socket not in a room');

socket.broadcast.to(documentId).emit('operation', operations);
await service.updateDocument(documentId, operations);
await service.updateDocument('documents', documentId, operations);
socket.emit('ack');
};
}
Expand Down
13 changes: 5 additions & 8 deletions code/server/src/ts/controllers/ws/namespaces/document/title.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { Socket } from 'socket.io';
import { DocumentService } from '@controllers/ws/types';
import { getRoomId } from '@controllers/ws/rooms';
import { InvalidParameterError } from '@domain/errors/errors';
import { DocumentService } from '@services/types';
import rooms from '@controllers/ws/rooms/rooms';

function title(service: DocumentService) {
return async function (socket: Socket, title: string) {
const documentId = getRoomId(socket);
if (!documentId) throw new InvalidParameterError('Client not in document');

await service.updateTitle(documentId, title);
socket.broadcast.to(documentId).emit('title', title);
const { id, workspaceId } = rooms.document.get(socket);
// TODO: update document title
// socket.broadcast.to(id).emit('title', title);
};
}

Expand Down
10 changes: 10 additions & 0 deletions code/server/src/ts/controllers/ws/namespaces/workspace/join.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Socket } from 'socket.io';
import rooms from '@controllers/ws/rooms/rooms';

function join() {
return function (socket: Socket, documentId: string) {
rooms.workspace.join(socket, documentId);
};
}

export default join;
10 changes: 10 additions & 0 deletions code/server/src/ts/controllers/ws/namespaces/workspace/leave.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Socket } from 'socket.io';
import rooms from '@controllers/ws/rooms/rooms';

function leave() {
return function (socket: Socket) {
rooms.workspace.leave(socket);
};
}

export default leave;
13 changes: 13 additions & 0 deletions code/server/src/ts/controllers/ws/namespaces/workspace/title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Socket } from 'socket.io';
import { DocumentService } from '@services/types';
import rooms from '@controllers/ws/rooms/rooms';

function title(service: DocumentService) {
return async function (socket: Socket, title: string) {
const { id } = rooms.document.get(socket);
// TODO: update workspace title
// socket.broadcast.to(id).emit('title', title);
};
}

export default title;
19 changes: 0 additions & 19 deletions code/server/src/ts/controllers/ws/rooms.ts

This file was deleted.

26 changes: 26 additions & 0 deletions code/server/src/ts/controllers/ws/rooms/Room.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Room {
private readonly roomId: string;
private users: string[] = [];

constructor(roomId: string) {
this.roomId = roomId;
}

join(userId: string) {
this.users.push(userId);
}

leave(userId: string) {
this.users = this.users.filter(id => id !== userId);
}

has(userId: string) {
return this.users.includes(userId);
}

get id() {
return this.roomId;
}
}

export default Room;
25 changes: 25 additions & 0 deletions code/server/src/ts/controllers/ws/rooms/roomOperations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Socket } from 'socket.io';
import Room from '@controllers/ws/rooms/Room';

export type RoomOperations = Map<string, Room>;

export function joinRoom(rooms: RoomOperations, socket: Socket, roomId: string) {
socket.join(roomId);
const room = rooms.get(roomId) || new Room(roomId);
room.join(socket.id);
rooms.set(roomId, room);
}

export function leaveRoom(rooms: RoomOperations, socket: Socket) {
const room = getRoom(rooms, socket);
if (!room) return;
socket.leave(room.id);
room.leave(socket.id);
}

export function getRoom(rooms: RoomOperations, socket: Socket): Room | null {
for (const room of rooms.values()) {
if (room.has(socket.id)) return room;
}
return null;
}
51 changes: 51 additions & 0 deletions code/server/src/ts/controllers/ws/rooms/rooms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Socket } from 'socket.io';
import Room from '@controllers/ws/rooms/Room';
import { getRoom, joinRoom, leaveRoom } from '@controllers/ws/rooms/roomOperations';
import { InvalidParameterError } from '@domain/errors/errors';

type Rooms = Map<string, Room>;
const workspaceRooms: Rooms = new Map(); // (documentId) => Room
const documentRooms: Rooms = new Map(); // (workspaceId) => Room

function joinDocument(socket: Socket, documentId: string) {
joinRoom(documentRooms, socket, documentId);
}

function leaveDocument(socket: Socket) {
leaveRoom(documentRooms, socket);
}

function getDocumentInfo(socket: Socket) {
const room = getRoom(documentRooms, socket);
if (!room) throw new InvalidParameterError('User not in document');
const workspaceInfo = getWorkspaceInfo(socket);
if (!workspaceInfo) throw new InvalidParameterError('User not in workspace');
return { id: room.id, workspaceId: workspaceInfo.id };
}

function joinWorkspace(socket: Socket, workspaceId: string) {
joinRoom(workspaceRooms, socket, workspaceId);
}

function leaveWorkspace(socket: Socket) {
leaveRoom(workspaceRooms, socket);
}

function getWorkspaceInfo(socket: Socket) {
const room = getRoom(workspaceRooms, socket);
if (!room) throw new InvalidParameterError('User not in workspace');
return { id: room.id };
}

export default {
document: {
join: joinDocument,
leave: leaveDocument,
get: getDocumentInfo,
},
workspace: {
join: joinWorkspace,
leave: leaveWorkspace,
get: getWorkspaceInfo,
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SocketNamespaces } from '@controllers/ws/types';
import { Server } from 'socket.io';

export function setupNamespaces(io: Server, events: SocketNamespaces) {
export function setupEventHandlers(io: Server, events: SocketNamespaces) {
Object.entries(events).forEach(([namespace, event]) => {
Object.entries(event).forEach(([name, handler]) => {
io.of(namespace).on('connection', socket => {
Expand Down
14 changes: 7 additions & 7 deletions code/server/src/ts/database/firestore/firestoreDB.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { cert, initializeApp, ServiceAccount } from 'firebase-admin/app';
import serviceAccount from './firestore-key-5cddf-472039f8dbb6.json';
import { getFirestore } from 'firebase-admin/firestore';
import { DocumentContent } from '@notespace/shared/workspace/types/document'
import { DocumentContent } from '@notespace/shared/workspace/types/document';
import { NotFoundError } from '@domain/errors/errors';
import { Operation } from '@notespace/shared/crdt/types/operations';
import { firestore } from 'firebase-admin';
Expand All @@ -21,7 +21,7 @@ export default function DocumentFirestoreDB(): DocumentDatabase {
* @param workspace
* @param id - the id of the document - must correspond to the id in postgres
*/
async function createDocument(workspace : string, id: string) {
async function createDocument(workspace: string, id: string) {
const documents = await getWorkspace(workspace);

const docData: DocumentContent = { operations: [] };
Expand All @@ -34,18 +34,18 @@ export default function DocumentFirestoreDB(): DocumentDatabase {
* @param workspace
* @param id
*/
async function getDocument(workspace : string, id: string): Promise<DocumentContent> {
const doc = await getDoc(workspace,id);
async function getDocument(workspace: string, id: string): Promise<DocumentContent> {
const doc = await getDoc(workspace, id);
const snapshot = await doc.get();
return snapshot.data() as DocumentContent;
}

async function deleteDocument(workspace : string, id: string) {
async function deleteDocument(workspace: string, id: string) {
const doc = await getDoc(workspace, id);
await doc.delete();
}

async function updateDocument(workspace : string, id: string, newOperations: Operation[]) {
async function updateDocument(workspace: string, id: string, newOperations: Operation[]) {
const doc = await getDoc(workspace, id);
await doc.update({ operations: FieldValue.arrayUnion(newOperations) });
}
Expand All @@ -54,7 +54,7 @@ export default function DocumentFirestoreDB(): DocumentDatabase {
return db.collection(workspace);
}

async function getDoc( workspace : string, id: string) {
async function getDoc(workspace: string, id: string) {
const documents = await getWorkspace(workspace);

const query = documents.where('id', '==', id);
Expand Down
8 changes: 4 additions & 4 deletions code/server/src/ts/database/memory/memoryDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ import { DocumentContent } from '@notespace/shared/workspace/types/document';
export default function DocumentMemoryDB(): DocumentDatabase {
const documents: Record<string, DocumentContent> = {};

async function createDocument(workspace : string, id : string) {
async function createDocument(workspace: string, id: string) {
documents[id] = { operations: [] };
return id;
}

async function getDocument(workspace : string, id: string): Promise<DocumentContent> {
async function getDocument(workspace: string, id: string): Promise<DocumentContent> {
const document = documents[id];
if (!document) throw new NotFoundError(`Document with id ${id} not found`);

return document;
}

async function deleteDocument(workspace : string, id: string) {
async function deleteDocument(workspace: string, id: string) {
const document = documents[id];
if (!document) throw new NotFoundError(`Document with id ${id} not found`);

delete documents[id];
}

async function updateDocument(workspace : string, id: string, operations: Operation[]) {
async function updateDocument(workspace: string, id: string, operations: Operation[]) {
const document = documents[id];
if (!document) throw new NotFoundError(`Document with id ${id} not found`);

Expand Down
2 changes: 1 addition & 1 deletion code/server/src/ts/database/pg/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ const credentials = {

const sql = postgres(credentials);

export default sql;
export default sql;
3 changes: 1 addition & 2 deletions code/server/src/ts/database/pg/postgresDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { WorkspaceResource } from '@notespace/shared/workspace/types/resource';

import sql from './database';


// export default function PostgresDB() : WorkspaceDatabase {
// async function getWorkspaceResources(workspace: string) : Promise<WorkspaceResource[]> {
// return sql`
Expand Down Expand Up @@ -32,4 +31,4 @@ import sql from './database';
// updateResource,
// deleteResource,
// };
// }
// }
20 changes: 10 additions & 10 deletions code/server/src/ts/database/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { Operation } from '@notespace/shared/crdt/types/operations';
import { WorkspaceResource } from '@notespace/shared/workspace/types/resource';

export type DocumentDatabase = {
createDocument: (workspace: string, id : string) => Promise<string>;
getDocument: (workspace : string, id: string) => Promise<DocumentStorageData>;
deleteDocument: (workspace : string, id: string) => Promise<void>;
updateDocument: (workspace : string, id: string, operations: Operation[]) => Promise<void>;
createDocument: (workspace: string, id: string) => Promise<string>;
getDocument: (workspace: string, id: string) => Promise<DocumentStorageData>;
deleteDocument: (workspace: string, id: string) => Promise<void>;
updateDocument: (workspace: string, id: string, operations: Operation[]) => Promise<void>;
};

export type WorkspaceDatabase = {
getWorkspaceResources : (workspace : string) => Promise<WorkspaceResource[]>;
createResource : (resource : WorkspaceResource) => Promise<string>;
getResource : (id : string) => Promise<WorkspaceResource>;
updateResource : (id : string, newProps : Partial<WorkspaceResource>) => Promise<void>;
deleteResource : (id : string) => Promise<void>;
}
getWorkspaceResources: (workspace: string) => Promise<WorkspaceResource[]>;
createResource: (resource: WorkspaceResource) => Promise<string>;
getResource: (id: string) => Promise<WorkspaceResource>;
updateResource: (id: string, newProps: Partial<WorkspaceResource>) => Promise<void>;
deleteResource: (id: string) => Promise<void>;
};
Loading

0 comments on commit 78c91c5

Please sign in to comment.