refactor: rootWorkspacesMetadataAtom loading logic (#2882)

This commit is contained in:
Alex Yang
2023-06-29 16:48:12 +08:00
parent df7f782e05
commit f7b07f4216
22 changed files with 436 additions and 353 deletions

View File

@@ -1,10 +1,12 @@
import { migrateToSubdoc } from '@affine/env/blocksuite';
import { isDesktop, isServer } from '@affine/env/constant';
import { setupGlobal } from '@affine/env/global';
import type { LocalIndexedDBDownloadProvider } from '@affine/env/workspace';
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
import type {
LocalIndexedDBDownloadProvider,
WorkspaceAdapter,
} from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace';
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
import { workspaceAdaptersAtom } from '@affine/workspace/atom';
import {
migrateLocalBlobStorage,
upgradeV1ToV2,
@@ -17,19 +19,27 @@ import { WorkspaceAdapters } from '../adapters/workspace';
setupGlobal();
rootStore.set(
workspaceAdaptersAtom,
WorkspaceAdapters as Record<
WorkspaceFlavour,
WorkspaceAdapter<WorkspaceFlavour>
>
);
if (process.env.NODE_ENV === 'development') {
console.log('Runtime Preset', runtimeConfig);
}
if (runtimeConfig.enablePlugin && !isServer) {
if (runtimeConfig.enablePlugin && !environment.isServer) {
import('@affine/copilot');
}
if (!isServer) {
if (!environment.isServer) {
import('@affine/bookmark-block');
}
if (!isDesktop && !isServer) {
if (!environment.isDesktop && !environment.isServer) {
// Polyfill Electron
const unimplemented = () => {
throw new Error('AFFiNE Plugin Web will be supported in the future');
@@ -52,65 +62,76 @@ if (!isDesktop && !isServer) {
});
}
rootStore.sub(rootWorkspacesMetadataAtom, () => {
const metadata = rootStore.get(rootWorkspacesMetadataAtom);
metadata.forEach(oldMeta => {
if (!oldMeta.version) {
const adapter = WorkspaceAdapters[oldMeta.flavour];
assertExists(adapter);
const upgrade = async () => {
const workspace = await adapter.CRUD.get(oldMeta.id);
if (!workspace) {
console.warn('cannot find workspace', oldMeta.id);
return;
}
if (workspace.flavour !== WorkspaceFlavour.LOCAL) {
console.warn('not supported');
return;
}
const doc = workspace.blockSuiteWorkspace.doc;
const provider = createIndexedDBDownloadProvider(workspace.id, doc, {
awareness: workspace.blockSuiteWorkspace.awarenessStore.awareness,
}) as LocalIndexedDBDownloadProvider;
provider.sync();
await provider.whenReady;
const newDoc = migrateToSubdoc(doc);
if (doc === newDoc) {
console.log('doc not changed');
rootStore.set(rootWorkspacesMetadataAtom, metadata =>
metadata.map(newMeta =>
newMeta.id === oldMeta.id
? {
...newMeta,
version: WorkspaceVersion.SubDoc,
}
: newMeta
)
);
return;
}
const newWorkspace = upgradeV1ToV2(workspace);
if (environment.isBrowser) {
const value = localStorage.getItem('jotai-workspaces');
if (value) {
try {
const metadata = JSON.parse(value) as RootWorkspaceMetadata[];
const promises: Promise<void>[] = [];
metadata.forEach(oldMeta => {
if (!('version' in oldMeta)) {
const adapter = WorkspaceAdapters[oldMeta.flavour];
assertExists(adapter);
const upgrade = async () => {
const workspace = await adapter.CRUD.get(oldMeta.id);
if (!workspace) {
console.warn('cannot find workspace', oldMeta.id);
return;
}
if (workspace.flavour !== WorkspaceFlavour.LOCAL) {
console.warn('not supported');
return;
}
const doc = workspace.blockSuiteWorkspace.doc;
const provider = createIndexedDBDownloadProvider(
workspace.id,
doc,
{
awareness:
workspace.blockSuiteWorkspace.awarenessStore.awareness,
}
) as LocalIndexedDBDownloadProvider;
provider.sync();
await provider.whenReady;
const newDoc = migrateToSubdoc(doc);
if (doc === newDoc) {
console.log('doc not changed');
return;
}
const newWorkspace = upgradeV1ToV2(workspace);
const newId = await adapter.CRUD.create(
newWorkspace.blockSuiteWorkspace
);
const newId = await adapter.CRUD.create(
newWorkspace.blockSuiteWorkspace
);
await adapter.CRUD.delete(workspace as any);
await migrateLocalBlobStorage(workspace.id, newId);
rootStore.set(rootWorkspacesMetadataAtom, metadata => [
...metadata
.map(newMeta => (newMeta.id === oldMeta.id ? null : newMeta))
.filter((meta): meta is RootWorkspaceMetadata => !!meta),
{
id: newId,
flavour: oldMeta.flavour,
version: WorkspaceVersion.SubDoc,
},
]);
};
await adapter.CRUD.delete(workspace as any);
await migrateLocalBlobStorage(workspace.id, newId);
};
// create a new workspace and push it to metadata
upgrade().catch(console.error);
// create a new workspace and push it to metadata
promises.push(upgrade());
}
});
Promise.all(promises)
.then(() => {
console.log('migration done');
})
.catch(() => {
console.error('migration failed');
})
.finally(() => {
window.dispatchEvent(new CustomEvent('migration-done'));
});
} catch (e) {
console.error('error when migrating data', e);
}
});
});
}
}
declare global {
// global Events
interface WindowEventMap {
'migration-done': CustomEvent;
}
}