Skip to content

Commit bb45ef8

Browse files
committed
Refactored Backend Structure & Fixed Tests
1 parent 0962481 commit bb45ef8

File tree

25 files changed

+221
-145
lines changed

25 files changed

+221
-145
lines changed

code/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"serve": "vite preview"
1717
},
1818
"dependencies": {
19-
"@notespace/shared": "link:..\\shared",
19+
"@notespace/shared": "file:..\\shared",
2020
"eslint-plugin-playwright": "^1.5.4",
2121
"lodash": "^4.17.21",
2222
"react": "^18.2.0",

code/server/.eslintrc.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
root: true,
3+
env: { node: true },
4+
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
5+
ignorePatterns: ['dist', '.eslintrc.cjs'],
6+
parser: '@typescript-eslint/parser',
7+
rules: {
8+
'@typescript-eslint/no-explicit-any': 'off',
9+
},
10+
};

code/server/jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
// eslint-disable-next-line @typescript-eslint/no-var-requires
2+
const { pathsToModuleNameMapper } = require('ts-jest');
3+
14
module.exports = {
25
preset: 'ts-jest',
36
testEnvironment: 'node',
7+
moduleNameMapper: pathsToModuleNameMapper({ '@src/*': ['./src/*'] }, { prefix: '<rootDir>/' }),
48
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Request, Response } from 'express';
2+
import { DocumentService } from '@src/types';
3+
4+
function deleteDocument(service: DocumentService) {
5+
return (req: Request, res: Response) => {
6+
service.deleteTree();
7+
res.status(200).send();
8+
};
9+
}
10+
11+
export default deleteDocument;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Request, Response } from 'express';
2+
import { DocumentService } from '@src/types';
3+
4+
function getDocument(service: DocumentService) {
5+
return async (req: Request, res: Response) => {
6+
const tree = await service.getTree();
7+
res.status(200).send(tree);
8+
};
9+
}
10+
11+
export default getDocument;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import express from 'express';
2+
import { DocumentService } from '@src/types';
3+
import getDocument from '@src/controllers/http/document/getDocument';
4+
import deleteDocument from '@src/controllers/http/document/deleteDocument';
5+
6+
export default function (service: DocumentService) {
7+
if (!service) {
8+
throw new Error('Service parameter is required');
9+
}
10+
const router = express.Router();
11+
router.use(express.urlencoded({ extended: true }));
12+
13+
router.get('/', (req, res) => {
14+
res.send('Welcome to NoteSpace');
15+
});
16+
router.get('/document', getDocument(service));
17+
router.delete('/document', deleteDocument(service));
18+
19+
return router;
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Socket } from 'socket.io';
2+
3+
const cursorColorsMap = new Map<string, string>();
4+
5+
function onCursorChange() {
6+
return (socket: Socket, position: CursorChangeData) => {
7+
if (!cursorColorsMap.has(socket.id)) {
8+
const randomColor = 'hsl(' + Math.random() * 360 + ', 100%, 75%)';
9+
cursorColorsMap.set(socket.id, randomColor);
10+
}
11+
const color = cursorColorsMap.get(socket.id);
12+
socket.broadcast.emit('cursorChange', { position, id: socket.id, color });
13+
};
14+
}
15+
16+
export default onCursorChange;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Socket } from 'socket.io';
2+
import { DocumentService } from '@src/types';
3+
import { Operation } from 'shared/crdt/types/operations';
4+
5+
function onOperation(service: DocumentService) {
6+
return (socket: Socket, operation: Operation) => {
7+
switch (operation.type) {
8+
case 'insert': {
9+
service.insertCharacter(operation);
10+
socket.broadcast.emit('operation', operation);
11+
break;
12+
}
13+
case 'delete': {
14+
service.deleteCharacter(operation);
15+
socket.broadcast.emit('operation', operation);
16+
break;
17+
}
18+
case 'style': {
19+
service.updateStyle(operation);
20+
socket.broadcast.emit('operation', operation);
21+
break;
22+
}
23+
default:
24+
throw new Error('Invalid operation type');
25+
}
26+
};
27+
}
28+
29+
export default onOperation;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import onOperation from '@src/controllers/socket/document/onOperation';
2+
import onCursorChange from '@src/controllers/socket/document/onCursorChange';
3+
import { DocumentService, SocketHandler } from '@src/types';
4+
5+
export default function events(service: DocumentService): Record<string, SocketHandler> {
6+
if (!service) {
7+
throw new Error('Service parameter is required');
8+
}
9+
return {
10+
operation: onOperation(service),
11+
cursorChange: onCursorChange,
12+
};
13+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Socket } from 'socket.io';
2+
import { DocumentService, SocketHandler } from '@src/types';
3+
4+
function onConnection(service: DocumentService, events: Record<string, SocketHandler>) {
5+
return async (socket: Socket) => {
6+
console.log('a client connected');
7+
8+
if (socket.connected) {
9+
const tree = await service.getTree();
10+
socket.emit('document', tree);
11+
}
12+
13+
Object.entries(events).forEach(([event, handler]) => {
14+
socket.on(event, data => {
15+
try {
16+
console.log(event);
17+
handler(socket, data);
18+
} catch (e) {
19+
socket.emit('error');
20+
console.error(e);
21+
}
22+
});
23+
});
24+
25+
socket.on('disconnect', reason => {
26+
console.log('a client disconnected', reason);
27+
});
28+
};
29+
}
30+
31+
export default onConnection;

0 commit comments

Comments
 (0)