Skip to content

Commit 3762ca6

Browse files
committed
refactor: initialize 코드 함수로 분리
1 parent f0d8217 commit 3762ca6

File tree

1 file changed

+144
-146
lines changed

1 file changed

+144
-146
lines changed

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

Lines changed: 144 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -75,62 +75,7 @@ export class YjsService
7575
// 노드를 클릭해 페이지를 열었을 때만 해당 페이지 값을 가져와서 초기 데이터로 세팅해줍니다.
7676
if (customDoc.name?.startsWith('document-')) {
7777
const pageId = parseInt(customDoc.name.split('-')[1]);
78-
79-
// 초기 세팅할 page content
80-
let pageContent: JSON;
81-
try {
82-
const findPage = await this.pageService.findPageById(pageId);
83-
pageContent = JSON.parse(JSON.stringify(findPage.content));
84-
} catch (exception) {
85-
// 에러 스택 출력
86-
this.logger.error(exception.stack);
87-
88-
// 만약 존재하지 않는 페이지에 접근한다면 비어있는 content를 전달한다.
89-
if (exception instanceof PageNotFoundException) {
90-
pageContent = JSON.parse('{}');
91-
return;
92-
}
93-
94-
throw exception;
95-
}
96-
97-
// content가 비어있다면 내부 구조가 novel editor schema를 따르지 않기 때문에 오류가 납니다.
98-
// content가 존재할 때만 넣어줍니다.
99-
// const pageContent = JSON.parse(JSON.stringify(findPage.content));
100-
// const novelEditorContent = {
101-
// type: 'doc',
102-
// content: pageContent,
103-
// };
104-
105-
if (Object.keys(pageContent).length > 0) {
106-
this.transformText(pageContent);
107-
// this.logger.error(this.transformText(pageContent));
108-
this.initializePageContent(pageContent, editorDoc);
109-
}
110-
// JSON.parse(findPage.content).length > 0 &&
111-
112-
// 페이지 내용 변경 사항을 감지해서 데이터베이스에 갱신합니다.
113-
editorDoc.observeDeep(() => {
114-
const document = editorDoc.doc as CustomDoc;
115-
const pageId = parseInt(document.name.split('-')[1]);
116-
117-
this.redisService.setField(
118-
`page:${pageId.toString()}`,
119-
'content',
120-
JSON.stringify(yXmlFragmentToProsemirrorJSON(editorDoc)),
121-
122-
);
123-
124-
// this.redisService.setField(
125-
// pageId.toString(),
126-
// 'content',
127-
// JSON.stringify(yXmlFragmentToProsemirrorJSON(editorDoc)),
128-
// );
129-
// this.redisService.get(pageId.toString()).then((data) => {
130-
// console.log(data);
131-
// });
132-
});
133-
return;
78+
this.initializePage(pageId, editorDoc);
13479
}
13580

13681
// 만약 페이지가 아닌 모든 노드들을 볼 수 있는 document라면 node, edge 초기 데이터를 세팅해줍니다.
@@ -142,96 +87,147 @@ export class YjsService
14287
return;
14388
}
14489

145-
// const workspaceId = customDoc.name.split('-')[2];
146-
// console.log('======', workspaceId);
14790
const workspaceId = 'main';
148-
const nodes = await this.nodeService.findNodesByWorkspace(workspaceId);
149-
const edges = await this.edgeService.findEdgesByWorkspace(workspaceId);
150-
const nodesMap = doc.getMap('nodes');
151-
const title = doc.getMap('title');
152-
const emoji = doc.getMap('emoji');
153-
const edgesMap = doc.getMap('edges');
154-
155-
this.initializeYNodeMap(nodes, nodesMap, title, emoji);
156-
this.initializeYEdgeMap(edges, edgesMap);
157-
158-
// title의 변경 사항을 감지한다.
159-
title.observeDeep(async (event) => {
160-
// path가 존재할 때만 페이지 갱신
161-
162-
event[0].path.toString().split('_')[1] &&
163-
this.redisService.setField(
164-
`page:${event[0].path.toString().split('_')[1]}`,
165-
'title',
166-
event[0].target.toString(),
91+
this.initializeWorkspace(workspaceId, doc);
92+
});
93+
}
16794

168-
);
169-
// this.redisService.setField(
170-
// event[0].path.toString().split('_')[1],
171-
// 'title',
172-
// event[0].target.toString(),
173-
// );
174-
});
175-
emoji.observeDeep((event) => {
176-
// path가 존재할 때만 페이지 갱신
177-
event[0].path.toString().split('_')[1] &&
178-
this.pageService.updatePage(
179-
parseInt(event[0].path.toString().split('_')[1]),
180-
{
181-
emoji: event[0].target.toString(),
182-
},
183-
);
184-
});
185-
// node의 변경 사항을 감지한다.
186-
nodesMap.observe(async (event) => {
187-
for (const [key, change] of event.changes.keys) {
188-
if (change.action === 'update') {
189-
const node: any = nodesMap.get(key);
190-
if (node.type !== 'note') {
191-
continue;
192-
}
193-
194-
// node.data는 페이지에 대한 정보
195-
const { title, id } = node.data;
196-
const { x, y } = node.position;
197-
const isHolding = node.isHolding;
198-
if (!isHolding) {
199-
// TODO : node의 경우 key 값을 page id가 아닌 node id로 변경
200-
const findPage = await this.pageService.findPageById(id);
201-
await this.nodeService.updateNode(findPage.node.id, {
202-
title,
203-
x,
204-
y,
205-
});
206-
}
95+
// yXmlFragment에 content를 넣어준다.
96+
private async initializePage(pageId: number, editorDoc: Y.XmlFragment) {
97+
// 초기 세팅할 page content
98+
let pageContent: JSON;
99+
try {
100+
const findPage = await this.pageService.findPageById(pageId);
101+
pageContent = JSON.parse(JSON.stringify(findPage.content));
102+
} catch (exception) {
103+
// 에러 스택 출력
104+
this.logger.error(exception.stack);
105+
106+
// 만약 존재하지 않는 페이지에 접근한다면 비어있는 content를 전달한다.
107+
if (exception instanceof PageNotFoundException) {
108+
pageContent = JSON.parse('{}');
109+
return;
110+
}
111+
112+
throw exception;
113+
}
114+
115+
// content가 비어있다면 내부 구조가 novel editor schema를 따르지 않기 때문에 오류가 납니다.
116+
// content가 존재할 때만 넣어줍니다.
117+
if (Object.keys(pageContent).length > 0) {
118+
this.transformText(pageContent);
119+
// this.logger.error(this.transformText(pageContent));
120+
prosemirrorJSONToYXmlFragment(novelEditorSchema, pageContent, editorDoc);
121+
}
122+
123+
// 페이지 내용 변경 사항을 감지해서 데이터베이스에 갱신합니다.
124+
editorDoc.observeDeep(() => {
125+
const document = editorDoc.doc as CustomDoc;
126+
const pageId = parseInt(document.name.split('-')[1]);
127+
128+
this.redisService.setField(
129+
`page:${pageId.toString()}`,
130+
'content',
131+
JSON.stringify(yXmlFragmentToProsemirrorJSON(editorDoc)),
132+
);
133+
});
134+
return;
135+
}
136+
137+
handleConnection() {
138+
this.logger.log('접속');
139+
}
140+
141+
handleDisconnect() {
142+
this.logger.log('접속 해제');
143+
}
144+
145+
146+
/**
147+
* initialize 관련 메소드
148+
*/
149+
private async initializeWorkspace(workspaceId: string, doc: Y.Doc) {
150+
// const workspaceId = customDoc.name.split('-')[2];
151+
// console.log('======', workspaceId);
152+
const nodes = await this.nodeService.findNodesByWorkspace(workspaceId);
153+
const edges = await this.edgeService.findEdgesByWorkspace(workspaceId);
154+
const nodesMap = doc.getMap('nodes');
155+
const title = doc.getMap('title');
156+
const emoji = doc.getMap('emoji');
157+
const edgesMap = doc.getMap('edges');
158+
159+
this.initializeYNodeMap(nodes, nodesMap, title, emoji);
160+
this.initializeYEdgeMap(edges, edgesMap);
161+
162+
// title의 변경 사항을 감지한다.
163+
title.observeDeep(async (event) => {
164+
// path가 존재할 때만 페이지 갱신
165+
166+
event[0].path.toString().split('_')[1] &&
167+
this.redisService.setField(
168+
`page:${event[0].path.toString().split('_')[1]}`,
169+
'title',
170+
event[0].target.toString(),
171+
);
172+
});
173+
emoji.observeDeep((event) => {
174+
// path가 존재할 때만 페이지 갱신
175+
event[0].path.toString().split('_')[1] &&
176+
this.pageService.updatePage(
177+
parseInt(event[0].path.toString().split('_')[1]),
178+
{
179+
emoji: event[0].target.toString(),
180+
},
181+
);
182+
});
183+
// node의 변경 사항을 감지한다.
184+
nodesMap.observe(async (event) => {
185+
for (const [key, change] of event.changes.keys) {
186+
if (change.action === 'update') {
187+
const node: any = nodesMap.get(key);
188+
if (node.type !== 'note') {
189+
continue;
190+
}
191+
192+
// node.data는 페이지에 대한 정보
193+
const { title, id } = node.data;
194+
const { x, y } = node.position;
195+
const isHolding = node.isHolding;
196+
if (!isHolding) {
197+
// TODO : node의 경우 key 값을 page id가 아닌 node id로 변경
198+
const findPage = await this.pageService.findPageById(id);
199+
await this.nodeService.updateNode(findPage.node.id, {
200+
title,
201+
x,
202+
y,
203+
});
207204
}
208205
}
209-
});
206+
}
207+
});
210208

211-
// edge의 변경 사항을 감지한다.
212-
edgesMap.observe(async (event) => {
213-
for (const [key, change] of event.changes.keys) {
214-
if (change.action === 'add') {
215-
const edge = edgesMap.get(key) as YMapEdge;
216-
const findEdge = await this.edgeService.findEdgeByFromNodeAndToNode(
217-
parseInt(edge.source),
218-
parseInt(edge.target),
219-
);
220-
// 연결된 노드가 없을 때만 edge 생성
221-
if (!findEdge) {
222-
await this.edgeService.createEdge({
223-
fromNode: parseInt(edge.source),
224-
toNode: parseInt(edge.target),
225-
});
226-
}
209+
// edge의 변경 사항을 감지한다.
210+
edgesMap.observe(async (event) => {
211+
for (const [key, change] of event.changes.keys) {
212+
if (change.action === 'add') {
213+
const edge = edgesMap.get(key) as YMapEdge;
214+
const findEdge = await this.edgeService.findEdgeByFromNodeAndToNode(
215+
parseInt(edge.source),
216+
parseInt(edge.target),
217+
);
218+
// 연결된 노드가 없을 때만 edge 생성
219+
if (!findEdge) {
220+
await this.edgeService.createEdge({
221+
fromNode: parseInt(edge.source),
222+
toNode: parseInt(edge.target),
223+
});
227224
}
228225
}
229-
});
226+
}
230227
});
231228
}
232-
233229
// YMap에 노드 정보를 넣어준다.
234-
initializeYNodeMap(
230+
private initializeYNodeMap(
235231
nodes: Node[],
236232
yNodeMap: Y.Map<unknown>,
237233
yTitleMap: Y.Map<unknown>,
@@ -279,7 +275,7 @@ export class YjsService
279275
}
280276

281277
// yMap에 edge 정보를 넣어준다.
282-
initializeYEdgeMap(edges: Edge[], yMap: Y.Map<unknown>): void {
278+
private initializeYEdgeMap(edges: Edge[], yMap: Y.Map<unknown>): void {
283279
edges.forEach((edge) => {
284280
const edgeId = edge.id.toString(); // id를 string으로 변환
285281

@@ -294,18 +290,23 @@ export class YjsService
294290
});
295291
}
296292

297-
// yXmlFragment에 content를 넣어준다.
298-
initializePageContent(content: JSON, yXmlFragment: Y.XmlFragment) {
299-
prosemirrorJSONToYXmlFragment(novelEditorSchema, content, yXmlFragment);
293+
/**
294+
* event listener 관련
295+
*/
296+
private observeTitle(){
297+
300298
}
301299

302-
handleConnection() {
303-
this.logger.log('접속');
300+
private observeEmoji(){
301+
302+
}
303+
private observeContent(){
304+
304305
}
305306

306307
// editor에서 paragraph 내부 text 노드의 text 값의 빈 문자열을 제거한다.
307308
// text 값이 빈 문자열이면 empty text nodes are not allowed 에러가 발생합니다.
308-
transformText(doc: any) {
309+
private transformText(doc: any) {
309310
doc.content.forEach((paragraph) => {
310311
if (paragraph.type === 'paragraph' && Array.isArray(paragraph.content)) {
311312
paragraph.content.forEach((textNode) => {
@@ -316,7 +317,4 @@ export class YjsService
316317
}
317318
});
318319
}
319-
handleDisconnect() {
320-
this.logger.log('접속 해제');
321-
}
322320
}

0 commit comments

Comments
 (0)