Skip to content

Commit 428419b

Browse files
authored
Merge pull request #194 from boostcampwm-2024/be-feature-#188
DB 데이터 저장 구현
2 parents e1ffb27 + a630937 commit 428419b

File tree

9 files changed

+148
-20
lines changed

9 files changed

+148
-20
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,8 @@ lerna-debug.log*
4444

4545
# IDE - VSCode
4646
.vscode/*
47-
apps/backend/db.sqlite
47+
!.vscode/settings.json
48+
!.vscode/tasks.json
49+
!.vscode/launch.json
50+
!.vscode/extensions.json
51+
db.sqlite

apps/backend/db

-36 KB
Binary file not shown.

apps/backend/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"class-transformer": "^0.5.1",
3535
"class-validator": "^0.14.1",
3636
"lib0": "^0.2.98",
37+
"node-ts-cache": "^4.4.0",
38+
"node-ts-cache-storage-memory": "^4.4.0",
3739
"path": "^0.12.7",
3840
"reflect-metadata": "^0.1.13",
3941
"rxjs": "^7.8.1",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Module, Global } from '@nestjs/common';
2+
import { NodeCacheService } from './node-cache.service';
3+
4+
@Global()
5+
@Module({
6+
providers: [NodeCacheService],
7+
exports: [NodeCacheService],
8+
})
9+
export class NodeCacheModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { CacheContainer } from 'node-ts-cache';
3+
import { MemoryStorage } from 'node-ts-cache-storage-memory';
4+
5+
@Injectable()
6+
export class NodeCacheService {
7+
private cache: CacheContainer;
8+
private ttlTime: number;
9+
10+
constructor() {
11+
this.ttlTime = 10;
12+
this.cache = new CacheContainer(new MemoryStorage());
13+
}
14+
15+
async set(nodeId: number, title: string): Promise<void> {
16+
const config = { ttl: this.ttlTime };
17+
await this.cache.setItem(nodeId.toString(), title, config);
18+
}
19+
20+
async get(nodeId: number): Promise<String | undefined> {
21+
return await this.cache.getItem<String>(nodeId.toString());
22+
}
23+
24+
async has(nodeId: number): Promise<boolean> {
25+
const item = await this.cache.getItem(nodeId.toString());
26+
return item !== undefined;
27+
}
28+
29+
async hasSameTitle(nodeId: number, title: string): Promise<boolean> {
30+
const savedTitle = await this.get(nodeId);
31+
return !!savedTitle && savedTitle === title;
32+
}
33+
}

apps/backend/src/page/page.service.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ export class PageService {
1414
) {}
1515

1616
async createPage(dto: CreatePageDto): Promise<Page> {
17-
const { title, content, x, y } = dto;
17+
const { title, x, y } = dto;
1818

19-
// 페이지부터 생성한다.
20-
const page = await this.pageRepository.save({ title, content });
19+
// 노드부터 생성한다.
20+
const node = await this.nodeRepository.save({ title, x, y });
2121

22-
// 노드를 생성한다.
23-
const node = await this.nodeRepository.save({ id: page.id, x, y });
22+
// 페이지를 생성한다.
23+
const page = await this.pageRepository.save({ title, content: {} });
2424

25-
// 노드와 페이지를 서로 연결하여 저장한다.
26-
page.node = node;
27-
return await this.pageRepository.save(page);
25+
// 페이지와 노드를 서로 연결하여 저장한다.
26+
node.page = page;
27+
await this.nodeRepository.save(node);
28+
return page;
2829
}
2930

3031
async createLinkedPage(title: string, nodeId: number): Promise<Page> {

apps/backend/src/yjs/yjs.module.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Module } from '@nestjs/common';
22
import { YjsService } from './yjs.service';
3+
import { NodeModule } from 'src/node/node.module';
4+
import { NodeCacheModule } from 'src/node-cache/node-cache.module';
35

46
@Module({
7+
imports: [NodeModule, NodeCacheModule],
58
providers: [YjsService],
69
})
710
export class YjsModule {}

apps/backend/src/yjs/yjs.service.ts

+33-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { Logger } from '@nestjs/common';
99
import { Server } from 'socket.io';
1010
import { YSocketIO } from 'y-socket.io/dist/server';
1111
import * as Y from 'yjs';
12+
import { NodeService } from '../node/node.service';
13+
import { NodeCacheService } from '../node-cache/node-cache.service';
1214

1315
@WebSocketGateway(1234)
1416
export class YjsService
@@ -17,6 +19,10 @@ export class YjsService
1719
private logger = new Logger('YjsGateway');
1820
private ysocketio: YSocketIO;
1921

22+
constructor(
23+
private readonly nodeService: NodeService,
24+
private readonly nodeCacheService: NodeCacheService,
25+
) {}
2026
@WebSocketServer()
2127
server: Server;
2228

@@ -32,20 +38,36 @@ export class YjsService
3238

3339
this.ysocketio.initialize();
3440

41+
this.ysocketio.on('document-update', (doc: Y.Doc) => {
42+
// console.log(doc.get("content").doc.share.get("content"));
43+
// console.log(doc.share.get('default'));
44+
});
45+
3546
this.ysocketio.on('document-loaded', (doc: Y.Doc) => {
36-
this.logger.log(`Document loaded: ${doc.guid}`);
47+
doc.on('update', () => {
48+
const nodes = Object.values(doc.getMap('nodes').toJSON());
49+
50+
// 모든 노드에 대해 검사한다.
51+
nodes.forEach((node) => {
52+
const { title, id } = node.data;
53+
const { x, y } = node.position;
54+
// 만약 캐쉬에 노드가 존재하지 않다면 갱신 후 캐쉬에 노드를 넣는다.
55+
if (!this.nodeCacheService.has(id)) {
56+
console.log(id);
57+
this.nodeService.updateNode(id, { title, x, y });
58+
this.nodeCacheService.set(id, title);
59+
return;
60+
}
3761

38-
const titleMap = doc.getMap('title');
39-
titleMap.observe(() => {
40-
console.log(titleMap.toString());
62+
// 만약 캐쉬에 노드가 존재하고 title이 다르다면 갱신한다.
63+
if (!this.nodeCacheService.hasSameTitle(id, title)) {
64+
this.nodeService.updateNode(id, { title, x, y });
65+
this.nodeCacheService.set(id, title);
66+
return;
67+
}
68+
// 만약 캐쉬에 노드가 존재하고 title이 동일하다면 패스한다.
69+
});
4170
});
42-
// const toggleMap = doc.getMap('toggleMap');
43-
// toggleMap.observe(() => {
44-
// const toggleState = toggleMap.get('toggle') || false;
45-
// this.logger.log('🐰 토글 상태 변경', {
46-
// toggleState,
47-
// });
48-
// });
4971
});
5072
}
5173

yarn.lock

+54
Original file line numberDiff line numberDiff line change
@@ -3045,6 +3045,11 @@ bl@^4.0.3, bl@^4.1.0:
30453045
inherits "^2.0.4"
30463046
readable-stream "^3.4.0"
30473047

3048+
3049+
version "3.7.2"
3050+
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
3051+
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
3052+
30483053
30493054
version "1.20.3"
30503055
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
@@ -3750,6 +3755,11 @@ delegates@^1.0.0:
37503755
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
37513756
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
37523757

3758+
denque@^1.5.0:
3759+
version "1.5.1"
3760+
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
3761+
integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
3762+
37533763
37543764
version "2.0.0"
37553765
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@@ -6604,6 +6614,23 @@ node-releases@^2.0.18:
66046614
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
66056615
integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
66066616

6617+
node-ts-cache-storage-memory@^4.4.0:
6618+
version "4.4.0"
6619+
resolved "https://registry.yarnpkg.com/node-ts-cache-storage-memory/-/node-ts-cache-storage-memory-4.4.0.tgz#d87da36bef0145c4d5a988191ffff6b9789c394e"
6620+
integrity sha512-eG8tFF4C1/RBmx52cS/dEu63l+Cn+Z6mz16nuTJwNyvtvDHWjsKKM3hg77PA7ddgf2ztaCyen8ZMQnLy191S4g==
6621+
dependencies:
6622+
debug "^4.3.2"
6623+
node-ts-cache "^4.4.0"
6624+
6625+
node-ts-cache@^4.4.0:
6626+
version "4.4.0"
6627+
resolved "https://registry.yarnpkg.com/node-ts-cache/-/node-ts-cache-4.4.0.tgz#ce10368537751d198565d15d1352bab5cc649252"
6628+
integrity sha512-ZULcxpzyFfgpOd33PHjwhPz4fkWSfyrwa9sq1j4jyOm+PaBpQDIzB3m5HRiSKdgEBtQhP3g6hX44dnMjnoHiPA==
6629+
dependencies:
6630+
bluebird "3.7.2"
6631+
debug "^4.3.2"
6632+
redis "^3.1.2"
6633+
66076634
nopt@^5.0.0:
66086635
version "5.0.0"
66096636
resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
@@ -7494,6 +7521,33 @@ readdirp@~3.6.0:
74947521
dependencies:
74957522
picomatch "^2.2.1"
74967523

7524+
redis-commands@^1.7.0:
7525+
version "1.7.0"
7526+
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
7527+
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
7528+
7529+
redis-errors@^1.0.0, redis-errors@^1.2.0:
7530+
version "1.2.0"
7531+
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
7532+
integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==
7533+
7534+
redis-parser@^3.0.0:
7535+
version "3.0.0"
7536+
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
7537+
integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==
7538+
dependencies:
7539+
redis-errors "^1.0.0"
7540+
7541+
redis@^3.1.2:
7542+
version "3.1.2"
7543+
resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c"
7544+
integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==
7545+
dependencies:
7546+
denque "^1.5.0"
7547+
redis-commands "^1.7.0"
7548+
redis-errors "^1.2.0"
7549+
redis-parser "^3.0.0"
7550+
74977551
reflect-metadata@^0.1.13:
74987552
version "0.1.14"
74997553
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859"

0 commit comments

Comments
 (0)