mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-25 01:39:53 +00:00
UBERF-7166 Use blob lookup for direct collaborative doc access (#5774)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
parent
673fc9910f
commit
f8b79226d9
@ -44,7 +44,7 @@
|
||||
import { textEditorCommandHandler } from '../commands'
|
||||
import { EditorKit } from '../kits/editor-kit'
|
||||
import textEditorPlugin from '../plugin'
|
||||
import { MinioProvider } from '../provider/minio'
|
||||
import { DirectStorageProvider } from '../provider/storage'
|
||||
import { TiptapCollabProvider } from '../provider/tiptap'
|
||||
import { formatCollaborativeDocumentId, formatPlatformDocumentId } from '../provider/utils'
|
||||
import {
|
||||
@ -135,7 +135,7 @@
|
||||
const ydoc = getContext<YDoc>(CollaborationIds.Doc) ?? new YDoc()
|
||||
const contextProvider = getContext<TiptapCollabProvider>(CollaborationIds.Provider)
|
||||
|
||||
const localProvider = contextProvider === undefined ? new MinioProvider(documentId, ydoc) : undefined
|
||||
const localProvider = contextProvider === undefined ? new DirectStorageProvider(collaborativeDoc, ydoc) : undefined
|
||||
|
||||
const remoteProvider: TiptapCollabProvider =
|
||||
contextProvider ??
|
||||
|
@ -1,68 +0,0 @@
|
||||
//
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import { parseDocumentId, type DocumentId } from '@hcengineering/collaborator-client'
|
||||
import { collaborativeDocParse, concatLink } from '@hcengineering/core'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import presentation, { getCurrentWorkspaceUrl } from '@hcengineering/presentation'
|
||||
import { ObservableV2 as Observable } from 'lib0/observable'
|
||||
import { applyUpdate, type Doc as YDoc } from 'yjs'
|
||||
|
||||
interface EVENTS {
|
||||
synced: (...args: any[]) => void
|
||||
}
|
||||
|
||||
async function fetchContent (doc: YDoc, name: string): Promise<void> {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
try {
|
||||
const frontUrl = getMetadata(presentation.metadata.FrontUrl) ?? window.location.origin
|
||||
|
||||
try {
|
||||
const res = await fetch(concatLink(frontUrl, `/files/${getCurrentWorkspaceUrl()}?file=${name}`))
|
||||
|
||||
if (res.ok) {
|
||||
const blob = await res.blob()
|
||||
const buffer = await blob.arrayBuffer()
|
||||
applyUpdate(doc, new Uint8Array(buffer))
|
||||
return
|
||||
}
|
||||
} catch {}
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
}
|
||||
// White a while
|
||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||
}
|
||||
}
|
||||
|
||||
export class MinioProvider extends Observable<EVENTS> {
|
||||
loaded: Promise<void>
|
||||
|
||||
constructor (documentId: DocumentId, doc: YDoc) {
|
||||
super()
|
||||
|
||||
this.loaded = new Promise((resolve) => {
|
||||
this.on('synced', resolve)
|
||||
})
|
||||
|
||||
const { collaborativeDoc } = parseDocumentId(documentId)
|
||||
const { documentId: minioDocumentId, versionId } = collaborativeDocParse(collaborativeDoc)
|
||||
|
||||
if (versionId === 'HEAD' && minioDocumentId !== undefined) {
|
||||
void fetchContent(doc, minioDocumentId).then(() => {
|
||||
this.emit('synced', [this])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
71
packages/text-editor/src/provider/storage.ts
Normal file
71
packages/text-editor/src/provider/storage.ts
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import { type Blob, type CollaborativeDoc, type Ref, collaborativeDocParse } from '@hcengineering/core'
|
||||
import { getBlobHref } from '@hcengineering/presentation'
|
||||
import { ObservableV2 as Observable } from 'lib0/observable'
|
||||
import { applyUpdate, type Doc as YDoc } from 'yjs'
|
||||
|
||||
interface EVENTS {
|
||||
synced: (...args: any[]) => void
|
||||
}
|
||||
|
||||
async function fetchContent (blob: Ref<Blob>, doc: YDoc): Promise<boolean> {
|
||||
const update = await fetchBlobContent(blob)
|
||||
if (update !== undefined) {
|
||||
applyUpdate(doc, update)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
async function fetchBlobContent (_id: Ref<Blob>): Promise<Uint8Array | undefined> {
|
||||
try {
|
||||
const href = await getBlobHref(undefined, _id)
|
||||
const res = await fetch(href)
|
||||
|
||||
if (res.ok) {
|
||||
const blob = await res.blob()
|
||||
const buffer = await blob.arrayBuffer()
|
||||
return new Uint8Array(buffer)
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
export class DirectStorageProvider extends Observable<EVENTS> {
|
||||
loaded: Promise<void>
|
||||
|
||||
constructor (collaborativeDoc: CollaborativeDoc, doc: YDoc) {
|
||||
super()
|
||||
|
||||
this.loaded = new Promise((resolve) => {
|
||||
this.on('synced', resolve)
|
||||
})
|
||||
|
||||
const { documentId, versionId } = collaborativeDocParse(collaborativeDoc)
|
||||
|
||||
if (versionId === 'HEAD') {
|
||||
void fetchContent(documentId as Ref<Blob>, doc).then((synced) => {
|
||||
if (synced) {
|
||||
this.emit('synced', [this])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user