fix: generate ydoc state during page import to prevent duplicate nodes on the editor

This commit is contained in:
Philipinho
2024-07-22 11:02:43 +01:00
parent d2ecd28047
commit 4d2936627c
2 changed files with 27 additions and 2 deletions

View File

@ -29,7 +29,9 @@ import {
} from '@docmost/editor-ext'; } from '@docmost/editor-ext';
import { generateText, JSONContent } from '@tiptap/core'; import { generateText, JSONContent } from '@tiptap/core';
import { generateHTML } from '../common/helpers/prosemirror/html'; import { generateHTML } from '../common/helpers/prosemirror/html';
// default tiptap library works best generating prosemirror json state // @tiptap/html library works best for generating prosemirror json state but not HTML
// see: https://github.com/ueberdosis/tiptap/issues/5352
// see:https://github.com/ueberdosis/tiptap/issues/4089
import { generateJSON } from '@tiptap/html'; import { generateJSON } from '@tiptap/html';
export const tiptapExtensions = [ export const tiptapExtensions = [

View File

@ -3,12 +3,17 @@ import { PageRepo } from '@docmost/db/repos/page/page.repo';
import { MultipartFile } from '@fastify/multipart'; import { MultipartFile } from '@fastify/multipart';
import { sanitize } from 'sanitize-filename-ts'; import { sanitize } from 'sanitize-filename-ts';
import * as path from 'path'; import * as path from 'path';
import { htmlToJson } from '../../collaboration/collaboration.util'; import {
htmlToJson,
tiptapExtensions,
} from '../../collaboration/collaboration.util';
import { InjectKysely } from 'nestjs-kysely'; import { InjectKysely } from 'nestjs-kysely';
import { KyselyDB } from '@docmost/db/types/kysely.types'; import { KyselyDB } from '@docmost/db/types/kysely.types';
import { generateSlugId } from '../../common/helpers'; import { generateSlugId } from '../../common/helpers';
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered'; import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
import { markdownToHtml } from './utils/marked.utils'; import { markdownToHtml } from './utils/marked.utils';
import { TiptapTransformer } from '@hocuspocus/transformer';
import * as Y from 'yjs';
@Injectable() @Injectable()
export class ImportService { export class ImportService {
@ -69,6 +74,7 @@ export class ImportService {
slugId: generateSlugId(), slugId: generateSlugId(),
title: pageTitle, title: pageTitle,
content: prosemirrorJson, content: prosemirrorJson,
ydoc: await this.createYdoc(prosemirrorJson),
position: pagePosition, position: pagePosition,
spaceId: spaceId, spaceId: spaceId,
creatorId: userId, creatorId: userId,
@ -106,6 +112,23 @@ export class ImportService {
} }
} }
async createYdoc(prosemirrorJson: any): Promise<Buffer | null> {
if (prosemirrorJson) {
this.logger.debug(`Converting prosemirror json state to ydoc`);
const ydoc = TiptapTransformer.toYdoc(
prosemirrorJson,
'default',
tiptapExtensions,
);
Y.encodeStateAsUpdate(ydoc);
return Buffer.from(Y.encodeStateAsUpdate(ydoc));
}
return null;
}
extractTitleAndRemoveHeading(prosemirrorState: any) { extractTitleAndRemoveHeading(prosemirrorState: any) {
let title = null; let title = null;