mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 22:38:56 +08:00
refactor(workspace): sync doc update in background using data source (#4081)
This commit is contained in:
@@ -1,15 +1,20 @@
|
||||
import { syncDataSource } from '@affine/y-provider';
|
||||
import { createIndexeddbStorage } from '@blocksuite/store';
|
||||
import { pushBinary } from '@toeverything/y-indexeddb';
|
||||
import {
|
||||
createIndexedDBDatasource,
|
||||
DEFAULT_DB_NAME,
|
||||
downloadBinary,
|
||||
} from '@toeverything/y-indexeddb';
|
||||
import type { Doc } from 'yjs';
|
||||
import { applyUpdate } from 'yjs';
|
||||
|
||||
import { createCloudBlobStorage } from '../blob/cloud-blob-storage';
|
||||
import { downloadBinaryFromCloud } from '../providers/cloud';
|
||||
import { createAffineDataSource } from '.';
|
||||
import { CRUD } from './crud';
|
||||
|
||||
let abortController: AbortController | undefined;
|
||||
|
||||
const downloadRecursive = async (
|
||||
const downloadRootFromIndexedDB = async (
|
||||
rootGuid: string,
|
||||
doc: Doc,
|
||||
signal: AbortSignal
|
||||
@@ -17,33 +22,43 @@ const downloadRecursive = async (
|
||||
if (signal.aborted) {
|
||||
return;
|
||||
}
|
||||
const binary = await downloadBinaryFromCloud(rootGuid, doc.guid);
|
||||
if (typeof binary !== 'boolean') {
|
||||
const update = new Uint8Array(binary);
|
||||
if (rootGuid === doc.guid) {
|
||||
// only apply the root doc
|
||||
applyUpdate(doc, update, 'affine-cloud-service');
|
||||
} else {
|
||||
await pushBinary(doc.guid, update);
|
||||
}
|
||||
const update = await downloadBinary(rootGuid);
|
||||
if (update !== false) {
|
||||
applyUpdate(doc, update);
|
||||
}
|
||||
return Promise.all(
|
||||
[...doc.subdocs.values()].map(subdoc =>
|
||||
downloadRecursive(rootGuid, subdoc, signal)
|
||||
)
|
||||
).then();
|
||||
};
|
||||
|
||||
export async function startSync() {
|
||||
if (!environment.isDesktop) {
|
||||
return;
|
||||
}
|
||||
abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const workspaces = await CRUD.list();
|
||||
const downloadCloudPromises = workspaces.map(workspace =>
|
||||
downloadRecursive(workspace.id, workspace.blockSuiteWorkspace.doc, signal)
|
||||
const syncDocPromises = workspaces.map(workspace =>
|
||||
downloadRootFromIndexedDB(
|
||||
workspace.id,
|
||||
workspace.blockSuiteWorkspace.doc,
|
||||
signal
|
||||
)
|
||||
);
|
||||
await Promise.all(syncDocPromises);
|
||||
const syncPromises = workspaces.map(workspace => {
|
||||
const remoteDataSource = createAffineDataSource(
|
||||
workspace.id,
|
||||
workspace.blockSuiteWorkspace.doc,
|
||||
workspace.blockSuiteWorkspace.awarenessStore.awareness
|
||||
);
|
||||
const indexeddbDataSource = createIndexedDBDatasource({
|
||||
dbName: DEFAULT_DB_NAME,
|
||||
});
|
||||
return syncDataSource(
|
||||
(): string[] => [
|
||||
workspace.blockSuiteWorkspace.doc.guid,
|
||||
...[...workspace.blockSuiteWorkspace.doc.subdocs].map(doc => doc.guid),
|
||||
],
|
||||
remoteDataSource,
|
||||
indexeddbDataSource
|
||||
);
|
||||
});
|
||||
|
||||
const syncBlobPromises = workspaces.map(async workspace => {
|
||||
const cloudBlobStorage = createCloudBlobStorage(workspace.id);
|
||||
const indexeddbBlobStorage = createIndexeddbStorage(workspace.id);
|
||||
@@ -88,7 +103,7 @@ export async function startSync() {
|
||||
]);
|
||||
});
|
||||
});
|
||||
await Promise.all([...downloadCloudPromises, ...syncBlobPromises]);
|
||||
await Promise.all([...syncPromises, ...syncBlobPromises]);
|
||||
}
|
||||
|
||||
export async function stopSync() {
|
||||
|
||||
Reference in New Issue
Block a user