diff --git a/.github/CLA.md b/.github/CLA.md index e9efea09b7..9340387c4c 100644 --- a/.github/CLA.md +++ b/.github/CLA.md @@ -56,5 +56,5 @@ Example: - Skye Sun, @skyesun, 2023/04/14 - Jordy Delgado, @Jdelgad8, 2023/04/17 - Howard Do, @howarddo2208, 2023/04/20 -- Kevin Deng, @sxzz, 2023/04/21 +- 三咲智子 Kevin Deng, @sxzz, 2023/04/21 - Moeyua, @moeyua, 2023/04/22 diff --git a/packages/y-indexeddb/src/__tests__/index.spec.ts b/packages/y-indexeddb/src/__tests__/index.spec.ts index c99247a393..350f40b1ad 100644 --- a/packages/y-indexeddb/src/__tests__/index.spec.ts +++ b/packages/y-indexeddb/src/__tests__/index.spec.ts @@ -13,6 +13,7 @@ import { applyUpdate, Doc, encodeStateAsUpdate } from 'yjs'; import type { WorkspacePersist } from '../index'; import { + CleanupWhenConnectingError, createIndexedDBProvider, dbVersion, DEFAULT_DB_NAME, @@ -59,7 +60,7 @@ describe('indexeddb provider', () => { await provider.whenSynced; const db = await openDB(rootDBName, dbVersion); { - const store = await db + const store = db .transaction('workspace', 'readonly') .objectStore('workspace'); const data = await store.get(id); @@ -161,6 +162,43 @@ describe('indexeddb provider', () => { expect(p1).not.toBe(p2); }); + test('cleanup', async () => { + const provider = createIndexedDBProvider(workspace.id, workspace.doc); + provider.connect(); + await provider.whenSynced; + const db = await openDB(rootDBName, dbVersion); + + { + const store = db + .transaction('workspace', 'readonly') + .objectStore('workspace'); + const keys = await store.getAllKeys(); + expect(keys).contain(workspace.id); + } + + provider.disconnect(); + await provider.cleanup(); + + { + const store = db + .transaction('workspace', 'readonly') + .objectStore('workspace'); + const keys = await store.getAllKeys(); + expect(keys).not.contain(workspace.id); + } + }); + + test('cleanup when connecting', async () => { + const provider = createIndexedDBProvider(workspace.id, workspace.doc); + provider.connect(); + expect(() => provider.cleanup()).rejects.toThrowError( + CleanupWhenConnectingError + ); + await provider.whenSynced; + provider.disconnect(); + await provider.cleanup(); + }); + test('merge', async () => { setMergeCount(5); const provider = createIndexedDBProvider( diff --git a/packages/y-indexeddb/src/index.ts b/packages/y-indexeddb/src/index.ts index c2ddc1d9f0..4d5e80ed7e 100644 --- a/packages/y-indexeddb/src/index.ts +++ b/packages/y-indexeddb/src/index.ts @@ -90,6 +90,12 @@ export class EarlyDisconnectError extends Error { } } +export class CleanupWhenConnectingError extends Error { + constructor() { + super('Cleanup when connecting'); + } +} + export const markMilestone = async ( id: string, doc: Doc, @@ -144,11 +150,11 @@ export const createIndexedDBProvider = ( let resolve: () => void; let reject: (reason?: unknown) => void; let early = true; - let connect = false; + let connected = false; async function handleUpdate(update: Uint8Array, origin: unknown) { const db = await dbPromise; - if (!connect) { + if (!connected) { return; } if (origin === indexeddbOrigin) { @@ -197,7 +203,7 @@ export const createIndexedDBProvider = ( upgrade: upgradeDB, }); const handleDestroy = async () => { - connect = true; + connected = true; const db = await dbPromise; db.close(); }; @@ -208,7 +214,7 @@ export const createIndexedDBProvider = ( resolve = _resolve; reject = _reject; }); - connect = true; + connected = true; doc.on('update', handleUpdate); doc.on('destroy', handleDestroy); // only run promise below, otherwise the logic is incorrect @@ -218,7 +224,7 @@ export const createIndexedDBProvider = ( .transaction('workspace', 'readwrite') .objectStore('workspace'); const data = await store.get(id); - if (!connect) { + if (!connected) { return; } if (!data) { @@ -267,15 +273,18 @@ export const createIndexedDBProvider = ( resolve(); }, disconnect() { - connect = false; + connected = false; if (early) { reject(new EarlyDisconnectError()); } doc.off('update', handleUpdate); doc.off('destroy', handleDestroy); }, - cleanup() { - // todo + async cleanup() { + if (connected) { + throw new CleanupWhenConnectingError(); + } + (await dbPromise).delete('workspace', id); }, whenSynced: Promise.resolve(), }; diff --git a/packages/y-indexeddb/src/shared.ts b/packages/y-indexeddb/src/shared.ts index 98ad6673d6..855c6c9613 100644 --- a/packages/y-indexeddb/src/shared.ts +++ b/packages/y-indexeddb/src/shared.ts @@ -11,7 +11,7 @@ export function upgradeDB(db: IDBPDatabase) { export interface IndexedDBProvider { connect: () => void; disconnect: () => void; - cleanup: () => void; + cleanup: () => Promise; whenSynced: Promise; }