mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-25 08:12:58 +03:00
fix(workspace): should avoid sending providers' update back (#3384)
This commit is contained in:
parent
2c249781a2
commit
6bafa83cef
@ -53,7 +53,7 @@ export const createSQLiteProvider: DocProviderCreator = (
|
||||
passive: true,
|
||||
connect: () => {
|
||||
datasource = createDatasource(id);
|
||||
provider = createLazyProvider(rootDoc, datasource);
|
||||
provider = createLazyProvider(rootDoc, datasource, { origin: 'sqlite' });
|
||||
provider.connect();
|
||||
connected = true;
|
||||
},
|
||||
|
@ -114,7 +114,7 @@ export const createIndexedDBProvider = (
|
||||
return {
|
||||
connect: () => {
|
||||
datasource = createDatasource({ dbName, mergeCount });
|
||||
provider = createLazyProvider(doc, datasource);
|
||||
provider = createLazyProvider(doc, datasource, { origin: 'idb' });
|
||||
provider.connect();
|
||||
},
|
||||
disconnect: () => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { applyUpdate, Doc, encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import { createLazyProvider } from '../lazy-provider';
|
||||
@ -178,4 +178,19 @@ describe('y-provider', () => {
|
||||
|
||||
expect(provider.connected).toBe(false);
|
||||
});
|
||||
|
||||
test('should not send remote update back', async () => {
|
||||
const remoteRootDoc = new Doc(); // this is the remote doc lives in remote
|
||||
const datasource = createMemoryDatasource(remoteRootDoc);
|
||||
const spy = vi.spyOn(datasource, 'sendDocUpdate');
|
||||
|
||||
const rootDoc = new Doc({ guid: remoteRootDoc.guid }); // this is the doc that we want to sync
|
||||
const provider = createLazyProvider(rootDoc, datasource);
|
||||
|
||||
provider.connect();
|
||||
|
||||
remoteRootDoc.getText('text').insert(0, 'test-value');
|
||||
|
||||
expect(spy).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
@ -9,8 +9,6 @@ import {
|
||||
|
||||
import type { DatasourceDocAdapter } from './types';
|
||||
|
||||
const selfUpdateOrigin = 'lazy-provider-self-origin';
|
||||
|
||||
function getDoc(doc: Doc, guid: string): Doc | undefined {
|
||||
if (doc.guid === guid) {
|
||||
return doc;
|
||||
@ -24,12 +22,17 @@ function getDoc(doc: Doc, guid: string): Doc | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
interface LazyProviderOptions {
|
||||
origin?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy provider that connects to a datasource and synchronizes a root document.
|
||||
*/
|
||||
export const createLazyProvider = (
|
||||
rootDoc: Doc,
|
||||
datasource: DatasourceDocAdapter
|
||||
datasource: DatasourceDocAdapter,
|
||||
options: LazyProviderOptions = {}
|
||||
): Omit<PassiveDocProvider, 'flavour'> => {
|
||||
let connected = false;
|
||||
const pendingMap = new Map<string, Uint8Array[]>(); // guid -> pending-updates
|
||||
@ -37,6 +40,8 @@ export const createLazyProvider = (
|
||||
const connectedDocs = new Set<string>();
|
||||
let datasourceUnsub: (() => void) | undefined;
|
||||
|
||||
const { origin = 'lazy-provider' } = options;
|
||||
|
||||
async function syncDoc(doc: Doc) {
|
||||
const guid = doc.guid;
|
||||
|
||||
@ -47,7 +52,7 @@ export const createLazyProvider = (
|
||||
pendingMap.set(guid, []);
|
||||
|
||||
if (remoteUpdate) {
|
||||
applyUpdate(doc, remoteUpdate, selfUpdateOrigin);
|
||||
applyUpdate(doc, remoteUpdate, origin);
|
||||
}
|
||||
|
||||
const sv = remoteUpdate
|
||||
@ -67,8 +72,8 @@ export const createLazyProvider = (
|
||||
function setupDocListener(doc: Doc) {
|
||||
const disposables = new Set<() => void>();
|
||||
disposableMap.set(doc.guid, disposables);
|
||||
const updateHandler = async (update: Uint8Array, origin: unknown) => {
|
||||
if (origin === selfUpdateOrigin) {
|
||||
const updateHandler = async (update: Uint8Array, updateOrigin: unknown) => {
|
||||
if (origin === updateOrigin) {
|
||||
return;
|
||||
}
|
||||
datasource.sendDocUpdate(doc.guid, update).catch(console.error);
|
||||
@ -100,10 +105,12 @@ export const createLazyProvider = (
|
||||
datasourceUnsub = datasource.onDocUpdate?.((guid, update) => {
|
||||
const doc = getDoc(rootDoc, guid);
|
||||
if (doc) {
|
||||
applyUpdate(doc, update);
|
||||
applyUpdate(doc, update, origin);
|
||||
//
|
||||
if (pendingMap.has(guid)) {
|
||||
pendingMap.get(guid)?.forEach(update => applyUpdate(doc, update));
|
||||
pendingMap
|
||||
.get(guid)
|
||||
?.forEach(update => applyUpdate(doc, update, origin));
|
||||
pendingMap.delete(guid);
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user