fix: merge two empty doc, no udpate event trigger

This commit is contained in:
alt0 2023-01-12 12:08:37 +08:00
parent 48d355ee72
commit 034e460701
4 changed files with 36 additions and 33 deletions

View File

@ -22,7 +22,7 @@ import {
syncToCloud,
} from './utils.js';
import { WorkspaceUnit } from '../../workspace-unit.js';
import { createBlocksuiteWorkspace } from '../../utils/index.js';
import { createBlocksuiteWorkspace, applyUpdate } from '../../utils/index.js';
import type { SyncMode } from '../../workspace-unit';
type ChannelMessage = {
@ -37,7 +37,7 @@ export interface AffineProviderConstructorParams
}
const {
Y: { applyUpdate, encodeStateAsUpdate },
Y: { encodeStateAsUpdate },
} = BlocksuiteWorkspace;
export class AffineProvider extends BaseProvider {
@ -160,12 +160,7 @@ export class AffineProvider extends BaseProvider {
const { doc, room: workspaceId } = blocksuiteWorkspace;
assert(workspaceId, 'Blocksuite Workspace without room(workspaceId).');
const updates = await this._apis.downloadWorkspace(workspaceId, published);
if (updates && updates.byteLength) {
await new Promise(resolve => {
doc.once('update', resolve);
BlocksuiteWorkspace.Y.applyUpdate(doc, new Uint8Array(updates));
});
}
await applyUpdate(blocksuiteWorkspace, new Uint8Array(updates));
}
override async loadPublicWorkspace(blocksuiteWorkspace: BlocksuiteWorkspace) {
@ -368,16 +363,11 @@ export class AffineProvider extends BaseProvider {
});
const blocksuiteWorkspace = createBlocksuiteWorkspace(id);
await new Promise(resolve => {
assert(workspaceUnit.blocksuiteWorkspace);
const doc = blocksuiteWorkspace.doc;
doc.once('update', resolve);
applyUpdate(
doc,
await applyUpdate(
blocksuiteWorkspace,
encodeStateAsUpdate(workspaceUnit.blocksuiteWorkspace.doc)
);
});
await syncToCloud(blocksuiteWorkspace, this._apis.token.refresh);

View File

@ -6,6 +6,7 @@ import { createBlocksuiteWorkspace } from '../../utils/index.js';
import type { Apis } from './apis';
import { WebsocketProvider } from './sync.js';
import { setDefaultAvatar } from '../utils.js';
import { applyUpdate } from '../../utils/index.js';
export const loadWorkspaceUnit = async (
params: WorkspaceUnitCtorParams,
@ -18,13 +19,7 @@ export const loadWorkspaceUnit = async (
workspaceUnit.id,
params.published
);
if (updates && updates.byteLength) {
await new Promise(resolve => {
const doc = blocksuiteWorkspace.doc;
doc.once('update', resolve);
BlocksuiteWorkspace.Y.applyUpdate(doc, new Uint8Array(updates));
});
}
applyUpdate(blocksuiteWorkspace, new Uint8Array(updates));
const details = await apis.getWorkspaceDetail({ id: workspaceUnit.id });
const owner = details?.owner;

View File

@ -1,9 +1,9 @@
import assert from 'assert';
import * as idb from 'lib0/indexeddb.js';
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
import { applyUpdate } from '../../../utils/index.js';
const { applyUpdate, encodeStateAsUpdate, mergeUpdates } =
BlocksuiteWorkspace.Y;
const { encodeStateAsUpdate, mergeUpdates } = BlocksuiteWorkspace.Y;
export const writeUpdatesToLocal = async (
blocksuiteWorkspace: BlocksuiteWorkspace
@ -34,12 +34,8 @@ export const applyLocalUpdates = async (
const [updatesStore] = idb.transact(db, ['updates']); // , 'readonly')
if (updatesStore) {
const updates = await idb.getAll(updatesStore);
const doc = blocksuiteWorkspace.doc;
await new Promise(resolve => {
const mergedUpdates = mergeUpdates(updates);
doc.once('update', resolve);
applyUpdate(doc, mergedUpdates);
});
await applyUpdate(blocksuiteWorkspace, mergedUpdates);
}
return blocksuiteWorkspace;
};

View File

@ -45,3 +45,25 @@ export async function getDefaultHeadImgBlob(
}
});
}
export const applyUpdate = async (
blocksuiteWorkspace: BlocksuiteWorkspace,
updates: Uint8Array
) => {
if (updates && updates.byteLength) {
await new Promise(resolve => {
// FIXME: if we merge two empty doc, there will no update event.
// So we set a timer to cancel update listener.
const doc = blocksuiteWorkspace.doc;
const timer = setTimeout(() => {
doc.off('update', resolve);
resolve(undefined);
}, 1000);
doc.once('update', () => {
clearTimeout(timer);
setTimeout(resolve, 100);
});
BlocksuiteWorkspace.Y.applyUpdate(doc, new Uint8Array(updates));
});
}
};