Skip to content

Commit 92680b0

Browse files
committed
fix: yDoc 세팅 데이터 형식 변경 및 document range error 해결
1 parent 380d08b commit 92680b0

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

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

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Node } from 'src/node/node.entity';
2121
import { Edge } from 'src/edge/edge.entity';
2222
import { YMapEdge } from './yjs.type';
2323
import { RedisService } from '../redis/redis.service';
24+
import { PageNotFoundException } from 'src/exception/page.exception';
2425

2526
// Y.Doc에는 name 컬럼이 없어서 생성했습니다.
2627
class CustomDoc extends Y.Doc {
@@ -36,7 +37,7 @@ class CustomDoc extends Y.Doc {
3637
export class YjsService
3738
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
3839
{
39-
private logger = new Logger('YjsGateway');
40+
private logger = new Logger(YjsService.name);
4041
private ysocketio: YSocketIO;
4142

4243
constructor(
@@ -69,20 +70,41 @@ export class YjsService
6970
// document name이 flow-room이라면 모든 노드들을 볼 수 있는 화면입니다.
7071
// 노드를 클릭해 페이지를 열었을 때만 해당 페이지 값을 가져와서 초기 데이터로 세팅해줍니다.
7172
if (customDoc.name?.startsWith('document-')) {
72-
const workspaceId = doc.guid;
7373
const pageId = parseInt(customDoc.name.split('-')[1]);
74-
const findPage = await this.pageService.findPageById(pageId);
74+
75+
// 초기 세팅할 page content
76+
let pageContent: JSON;
77+
try {
78+
const findPage = await this.pageService.findPageById(pageId);
79+
pageContent = JSON.parse(JSON.stringify(findPage.content));
80+
} catch (exception) {
81+
// 에러 스택 출력
82+
this.logger.error(exception.stack);
83+
84+
// 만약 존재하지 않는 페이지에 접근한다면 비어있는 content를 전달한다.
85+
if (exception instanceof PageNotFoundException) {
86+
pageContent = JSON.parse('{}');
87+
return;
88+
}
89+
90+
throw exception;
91+
}
7592

7693
// content가 비어있다면 내부 구조가 novel editor schema를 따르지 않기 때문에 오류가 납니다.
7794
// content가 존재할 때만 넣어줍니다.
78-
const pageContent = JSON.parse(JSON.stringify(findPage.content));
79-
const novelEditorContent = {
80-
type: 'doc',
81-
content: pageContent,
82-
};
83-
pageContent.length > 0 &&
84-
// JSON.parse(findPage.content).length > 0 &&
85-
this.initializePageContent(novelEditorContent, editorDoc);
95+
// const pageContent = JSON.parse(JSON.stringify(findPage.content));
96+
// const novelEditorContent = {
97+
// type: 'doc',
98+
// content: pageContent,
99+
// };
100+
101+
if (Object.keys(pageContent).length > 0) {
102+
this.transformText(pageContent);
103+
this.logger.error(pageContent);
104+
// this.logger.error(this.transformText(pageContent));
105+
this.initializePageContent(pageContent, editorDoc);
106+
}
107+
// JSON.parse(findPage.content).length > 0 &&
86108

87109
// 페이지 내용 변경 사항을 감지해서 데이터베이스에 갱신합니다.
88110
editorDoc.observeDeep(() => {
@@ -202,6 +224,10 @@ export class YjsService
202224
yTitleMap: Y.Map<unknown>,
203225
yEmojiMap: Y.Map<unknown>,
204226
): void {
227+
// 초기화
228+
yNodeMap.clear();
229+
yTitleMap.clear();
230+
yEmojiMap.clear();
205231
nodes.forEach((node) => {
206232
const nodeId = node.id.toString(); // id를 string으로 변환
207233

@@ -256,14 +282,26 @@ export class YjsService
256282
}
257283

258284
// yXmlFragment에 content를 넣어준다.
259-
initializePageContent(content: unknown, yXmlFragment: Y.XmlFragment) {
285+
initializePageContent(content: JSON, yXmlFragment: Y.XmlFragment) {
260286
prosemirrorJSONToYXmlFragment(novelEditorSchema, content, yXmlFragment);
261287
}
262288

263289
handleConnection() {
264290
this.logger.log('접속');
265291
}
266292

293+
// editor에서 paragraph 내부 text 노드의 text 값의 빈 문자열을 제거한다.
294+
transformText(doc: any) {
295+
doc.content.forEach((paragraph) => {
296+
if (paragraph.type === 'paragraph' && Array.isArray(paragraph.content)) {
297+
paragraph.content.forEach((textNode) => {
298+
if (textNode.type === 'text' && textNode.text === '') {
299+
textNode.text = ' '; // 빈 문자열을 "a"로 대체
300+
}
301+
});
302+
}
303+
});
304+
}
267305
handleDisconnect() {
268306
this.logger.log('접속 해제');
269307
}

0 commit comments

Comments
 (0)