UBERF-8499: Use our generateId for ydocs (#6958)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-10-16 20:16:41 +07:00 committed by GitHub
parent e6d9b8f606
commit 51679bf82c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 44 additions and 31 deletions

View File

@ -13,7 +13,7 @@
// limitations under the License.
//
import { Markup } from '@hcengineering/core'
import { generateId, Markup } from '@hcengineering/core'
import { Extensions, getSchema } from '@tiptap/core'
import { Node, Schema } from '@tiptap/pm/model'
import { prosemirrorJSONToYDoc, prosemirrorToYDoc, yDocToProsemirrorJSON } from 'y-prosemirror'
@ -50,7 +50,7 @@ export function jsonToYDocNoSchema (json: MarkupNode, field: string): YDoc {
const nodes = json.type === 'doc' ? json.content ?? [] : [json]
const content = nodes.map(nodeToYXmlElement)
const ydoc = new YDoc()
const ydoc = new YDoc({ guid: generateId() })
const fragment = ydoc.getXmlFragment(field)
fragment.push(content)
@ -113,7 +113,10 @@ export function yDocContentToNodes (content: ArrayBuffer, schema?: Schema, exten
const nodes: Node[] = []
try {
const ydoc = new YDoc()
const ydoc = new YDoc({
gc: false,
guid: generateId()
})
const uint8arr = new Uint8Array(content)
applyUpdate(ydoc, uint8arr)
@ -144,8 +147,8 @@ export function updateYDocContent (
schema ??= extensions === undefined ? defaultSchema : getSchema(extensions ?? defaultExtensions)
try {
const ydoc = new YDoc({ gc: false })
const res = new YDoc({ gc: false })
const ydoc = new YDoc({ guid: generateId(), gc: false })
const res = new YDoc({ guid: generateId(), gc: false })
const uint8arr = new Uint8Array(content)
applyUpdate(ydoc, uint8arr)

View File

@ -16,7 +16,7 @@
-->
<script lang="ts">
import { Analytics } from '@hcengineering/analytics'
import { type Space, type Class, type CollaborativeDoc, type Doc, type Ref } from '@hcengineering/core'
import { type Space, type Class, type CollaborativeDoc, type Doc, type Ref, generateId } from '@hcengineering/core'
import { IntlString, translate } from '@hcengineering/platform'
import { getFileUrl, getImageSize, imageSizeToRatio } from '@hcengineering/presentation'
import { markupToJSON } from '@hcengineering/text'
@ -102,7 +102,7 @@
const dispatch = createEventDispatcher()
const ydoc = getContext<YDoc>(CollaborationIds.Doc) ?? new YDoc()
const ydoc = getContext<YDoc>(CollaborationIds.Doc) ?? new YDoc({ guid: generateId() })
const contextProvider = getContext<Provider>(CollaborationIds.Provider)
const localProvider = createLocalProvider(ydoc, collaborativeDoc)

View File

@ -13,7 +13,7 @@
// limitations under the License.
//
import { type Ref, type CollaborativeDoc, type Doc, type Class } from '@hcengineering/core'
import { type Ref, type CollaborativeDoc, type Doc, type Class, generateId } from '@hcengineering/core'
import {
type DocumentId,
type PlatformDocumentId,
@ -99,7 +99,7 @@ export const createTiptapCollaborationData = (params: {
objectId?: Ref<Doc>
objectAttr?: string
}): { provider: Provider, ydoc: Ydoc } => {
const ydoc: Ydoc = new Ydoc()
const ydoc: Ydoc = new Ydoc({ guid: generateId() })
return {
ydoc,
provider: createRemoteProvider(ydoc, params)

View File

@ -16,11 +16,12 @@
import { Doc as YDoc, encodeStateAsUpdate, encodeStateVector } from 'yjs'
import { yDocBranch, yDocBranchWithGC } from '../branch'
import { generateId } from '@hcengineering/core'
describe('branch', () => {
describe('yDocBranch', () => {
it('branches document without gc', async () => {
const source = new YDoc({ gc: false })
const source = new YDoc({ guid: generateId(), gc: false })
applyGarbageCollectableChanges(source)
@ -45,7 +46,7 @@ describe('branch', () => {
})
it('branches document state with gc', async () => {
const source = new YDoc({ gc: true })
const source = new YDoc({ guid: generateId(), gc: true })
applyGarbageCollectableChanges(source)
@ -72,7 +73,7 @@ describe('branch', () => {
describe('yDocBranchWithGC', () => {
it('branches document state without gc', async () => {
const source = new YDoc({ gc: false })
const source = new YDoc({ guid: generateId(), gc: false })
applyGarbageCollectableChanges(source)
@ -97,7 +98,7 @@ describe('branch', () => {
})
it('branches document state with gc', async () => {
const source = new YDoc({ gc: true })
const source = new YDoc({ guid: generateId(), gc: true })
applyGarbageCollectableChanges(source)

View File

@ -25,7 +25,7 @@ describe('history', () => {
let ydoc: YDoc
beforeEach(() => {
ydoc = new YDoc()
ydoc = new YDoc({ guid: generateId() })
})
it('addVersion should append new version', async () => {

View File

@ -16,8 +16,8 @@
import { Account, Ref, generateId } from '@hcengineering/core'
import { Doc as YDoc } from 'yjs'
import { createYdocSnapshot, restoreYdocSnapshot } from '../snapshot'
import { YDocVersion } from '../history'
import { createYdocSnapshot, restoreYdocSnapshot } from '../snapshot'
const HISTORY = 'history'
const UPDATES = 'updates'
@ -27,8 +27,8 @@ describe('snapshot', () => {
let yHistory: YDoc
beforeEach(() => {
yContent = new YDoc({ gc: false })
yHistory = new YDoc()
yContent = new YDoc({ guid: generateId(), gc: false })
yHistory = new YDoc({ guid: generateId() })
})
it('createYdocSnapshot appends new version', async () => {
@ -74,7 +74,7 @@ describe('snapshot', () => {
const versionId = generateId()
const version = yDocVersion(versionId)
yContent = new YDoc({ gc: true })
yContent = new YDoc({ guid: generateId(), gc: true })
createYdocSnapshot(yContent, yHistory, version)
expect(() => restoreYdocSnapshot(yContent, yHistory, versionId)).toThrow()
})

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
import { generateId } from '@hcengineering/core'
import { Doc as YDoc, applyUpdate, encodeStateAsUpdate } from 'yjs'
/**
@ -25,7 +26,7 @@ import { Doc as YDoc, applyUpdate, encodeStateAsUpdate } from 'yjs'
* @public
* */
export function yDocBranch (source: YDoc): YDoc {
const target = new YDoc({ gc: source.gc })
const target = new YDoc({ guid: generateId(), gc: source.gc })
const update = encodeStateAsUpdate(source)
applyUpdate(target, update)
@ -43,9 +44,9 @@ export function yDocBranch (source: YDoc): YDoc {
* @public
* */
export function yDocBranchWithGC (source: YDoc): YDoc {
const target = new YDoc({ gc: source.gc })
const target = new YDoc({ guid: generateId(), gc: source.gc })
const gc = new YDoc({ gc: true })
const gc = new YDoc({ guid: generateId(), gc: true })
applyUpdate(gc, encodeStateAsUpdate(source))
applyUpdate(target, encodeStateAsUpdate(gc))

View File

@ -16,22 +16,23 @@
import { Doc as YDoc, XmlElement as YXmlElement, XmlText as YXmlText, encodeStateVector } from 'yjs'
import { clone, yDocCopyXmlField, yDocFromBuffer, yDocToBuffer } from '../ydoc'
import { generateId } from '@hcengineering/core'
describe('ydoc', () => {
it('yDocFromBuffer converts ydoc to a buffer', async () => {
const ydoc = new YDoc()
const ydoc = new YDoc({ guid: generateId() })
const buffer = yDocToBuffer(ydoc)
expect(buffer).toBeDefined()
})
it('yDocFromBuffer converts buffer to a ydoc', async () => {
const source = new YDoc()
const source = new YDoc({ guid: generateId() })
source.getArray('data').insert(0, [1, 2])
const buffer = yDocToBuffer(source)
const target = yDocFromBuffer(buffer, new YDoc())
const target = yDocFromBuffer(buffer, new YDoc({ guid: generateId() }))
expect(target).toBeDefined()
expect(encodeStateVector(target)).toEqual(encodeStateVector(source))
})

View File

@ -20,7 +20,8 @@ import {
MeasureContext,
WorkspaceId,
collaborativeDocParse,
collaborativeDocUnchain
collaborativeDocUnchain,
generateId
} from '@hcengineering/core'
import { Doc as YDoc } from 'yjs'
@ -42,7 +43,13 @@ async function loadCollaborativeDocVersion (
versionId: string
): Promise<YDoc | undefined> {
const yContent = await ctx.with('yDocFromStorage', { type: 'content' }, async (ctx) => {
return await yDocFromStorage(ctx, storageAdapter, workspace, documentId, new YDoc({ gc: false }))
return await yDocFromStorage(
ctx,
storageAdapter,
workspace,
documentId,
new YDoc({ guid: generateId(), gc: false })
)
})
// the document does not exist
@ -56,7 +63,7 @@ async function loadCollaborativeDocVersion (
const historyDocumentId = collaborativeHistoryDocId(documentId)
const yHistory = await ctx.with('yDocFromStorage', { type: 'history' }, async (ctx) => {
return await yDocFromStorage(ctx, storageAdapter, workspace, historyDocumentId, new YDoc())
return await yDocFromStorage(ctx, storageAdapter, workspace, historyDocumentId, new YDoc({ guid: generateId() }))
})
// the history document does not exist

View File

@ -13,7 +13,7 @@
// limitations under the License.
//
import { MeasureContext, WorkspaceId } from '@hcengineering/core'
import { generateId, MeasureContext, WorkspaceId } from '@hcengineering/core'
import { StorageAdapter } from '@hcengineering/server-core'
import { Doc as YDoc } from 'yjs'
@ -35,10 +35,10 @@ export async function yDocFromStorage (
// no need to apply gc because we load existing document
// it is either already gc-ed, or gc not needed and it is disabled
ydoc ??= new YDoc({ gc: false })
ydoc ??= new YDoc({ guid: generateId(), gc: false })
const buffer = await storageAdapter.read(ctx, workspace, documentId)
return yDocFromBuffer(Buffer.concat(buffer), ydoc)
return yDocFromBuffer(Buffer.concat(buffer as any), ydoc)
}
/** @public */

View File

@ -50,7 +50,7 @@ export async function createRekoniAdapter (
}
return r.content
} catch (err: any) {
console.info('Content Processing error', name, type, doc, err.response.body)
console.info('Content Processing error', name, type, doc, err)
if (err.message === 'Response code 400 (Bad Request)' || err.code === 400) {
return ''
}