Skip to content

Commit

Permalink
feat(nbstore): add doc sync frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
EYHN committed Dec 10, 2024
1 parent 35edf38 commit 4ec8459
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 58 deletions.
50 changes: 50 additions & 0 deletions packages/common/nbstore/src/__tests__/frontend.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'fake-indexeddb/auto';

import { test, vitest } from 'vitest';
import { Doc as YDoc } from 'yjs';

import { DocFrontend } from '../frontend/doc';
import { IndexedDBDocStorage } from '../impls/idb';
import { expectYjsEqual } from './utils';

test('doc', async () => {
const doc1 = new YDoc({
guid: 'test-doc',
});
doc1.getMap('test').set('hello', 'world');

const docStorage = new IndexedDBDocStorage({
id: 'ws1',
peer: 'a',
type: 'workspace',
});

await docStorage.connect();

const frontend1 = new DocFrontend(docStorage, null);
frontend1.start();
frontend1.addDoc(doc1);
await vitest.waitFor(async () => {
const doc = await docStorage.getDoc('test-doc');
expectYjsEqual(doc!.bin, {
test: {
hello: 'world',
},
});
});

const doc2 = new YDoc({
guid: 'test-doc',
});
const frontend2 = new DocFrontend(docStorage, null);
frontend2.start();
frontend2.addDoc(doc2);

await vitest.waitFor(async () => {
expectYjsEqual(doc2, {
test: {
hello: 'world',
},
});
});
});
37 changes: 25 additions & 12 deletions packages/common/nbstore/src/__tests__/sync.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '../impls/idb';
import { SpaceStorage } from '../storage';
import { SyncEngine } from '../sync';
import { expectYjsEqual } from './utils';

test('doc', async () => {
const doc = new YDoc();
Expand Down Expand Up @@ -53,19 +54,24 @@ test('doc', async () => {
});

const sync = new SyncEngine(peerA, [peerB, peerC]);
const abort = new AbortController();
sync.run(abort.signal);
sync.start();

await new Promise(resolve => setTimeout(resolve, 1000));

{
const b = await peerB.get('doc').getDoc('doc1');
expect(b).not.toBeNull();
expect(b?.bin).toEqual(update);
expectYjsEqual(b!.bin, {
test: {
hello: 'world',
},
});

const c = await peerC.get('doc').getDoc('doc1');
expect(c).not.toBeNull();
expect(c?.bin).toEqual(update);
expectYjsEqual(c!.bin, {
test: {
hello: 'world',
},
});
}

doc.getMap('test').set('foo', 'bar');
Expand All @@ -79,12 +85,20 @@ test('doc', async () => {

{
const a = await peerA.get('doc').getDoc('doc1');
expect(a).not.toBeNull();
expect(a?.bin).toEqual(update2);
expectYjsEqual(a!.bin, {
test: {
hello: 'world',
foo: 'bar',
},
});

const c = await peerC.get('doc').getDoc('doc1');
expect(c).not.toBeNull();
expect(c?.bin).toEqual(update2);
expectYjsEqual(c!.bin, {
test: {
hello: 'world',
foo: 'bar',
},
});
}
});

Expand Down Expand Up @@ -130,8 +144,7 @@ test('blob', async () => {
await peerC.connect();

const sync = new SyncEngine(peerA, [peerB, peerC]);
const abort = new AbortController();
sync.run(abort.signal);
sync.start();

await new Promise(resolve => setTimeout(resolve, 1000));

Expand Down
30 changes: 30 additions & 0 deletions packages/common/nbstore/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect } from 'vitest';
import { applyUpdate, Doc as YDoc } from 'yjs';

export function expectYjsEqual(
doc: Uint8Array | YDoc,
match: Record<string, any>
) {
let ydoc: YDoc;
if (doc instanceof Uint8Array) {
ydoc = new YDoc();
applyUpdate(ydoc, doc);
} else {
ydoc = doc;
}

for (const key in match) {
const value = match[key];
if (Array.isArray(value)) {
const actual = ydoc.getArray(key).toJSON();
expect(actual).toEqual(value);
} else if (typeof value === 'string') {
const actual = ydoc.getText(key).toJSON();
expect(actual).toEqual(value);
} else {
const actual = ydoc.getMap(key).toJSON();
expect(actual).toEqual(value);
}
}
return doc;
}
Loading

0 comments on commit 4ec8459

Please sign in to comment.