mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-06 20:10:24 +08:00
Merge branch 'feat/cloud-sync-saika' into feat/datacenter-dev
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
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 { encodeStateAsUpdate } = BlocksuiteWorkspace.Y;
|
||||
const { encodeStateAsUpdate, mergeUpdates } = BlocksuiteWorkspace.Y;
|
||||
|
||||
export const initStore = async (blocksuiteWorkspace: BlocksuiteWorkspace) => {
|
||||
export const writeUpdatesToLocal = async (
|
||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||
) => {
|
||||
const workspaceId = blocksuiteWorkspace.room;
|
||||
assert(workspaceId);
|
||||
await idb.deleteDB(workspaceId);
|
||||
@@ -18,3 +21,21 @@ export const initStore = async (blocksuiteWorkspace: BlocksuiteWorkspace) => {
|
||||
await idb.addAutoKey(updatesStore, currState);
|
||||
}
|
||||
};
|
||||
|
||||
export const applyLocalUpdates = async (
|
||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||
) => {
|
||||
const workspaceId = blocksuiteWorkspace.room;
|
||||
assert(workspaceId, 'Blocksuite workspace without room(workspaceId).');
|
||||
const db = await idb.openDB(workspaceId, db =>
|
||||
idb.createStores(db, [['updates', { autoIncrement: true }], ['custom']])
|
||||
);
|
||||
|
||||
const [updatesStore] = idb.transact(db, ['updates']); // , 'readonly')
|
||||
if (updatesStore) {
|
||||
const updates = await idb.getAll(updatesStore);
|
||||
const mergedUpdates = mergeUpdates(updates);
|
||||
await applyUpdate(blocksuiteWorkspace, mergedUpdates);
|
||||
}
|
||||
return blocksuiteWorkspace;
|
||||
};
|
||||
|
||||
@@ -16,12 +16,10 @@ test.describe.serial('local provider', () => {
|
||||
let workspaceId: string | undefined;
|
||||
|
||||
test('create workspace', async () => {
|
||||
const workspaceInfo = await provider.createWorkspaceInfo({
|
||||
const workspaceUnit = await provider.createWorkspace({
|
||||
name: workspaceName,
|
||||
});
|
||||
workspaceId = workspaceInfo.id;
|
||||
const blocksuiteWorkspace = createBlocksuiteWorkspace(workspaceId);
|
||||
await provider.createWorkspace(blocksuiteWorkspace, workspaceInfo);
|
||||
workspaceId = workspaceUnit?.id;
|
||||
|
||||
expect(workspaceMetaCollection.workspaces.length).toEqual(1);
|
||||
expect(workspaceMetaCollection.workspaces[0].name).toEqual(workspaceName);
|
||||
|
||||
@@ -8,9 +8,9 @@ import type {
|
||||
import { varStorage as storage } from 'lib0/storage';
|
||||
import { Workspace as BlocksuiteWorkspace, uuidv4 } from '@blocksuite/store';
|
||||
import { IndexedDBProvider } from './indexeddb/indexeddb.js';
|
||||
import { initStore } from './indexeddb/utils.js';
|
||||
import assert from 'assert';
|
||||
import { setDefaultAvatar } from '../utils.js';
|
||||
import { loadWorkspaceUnit, createWorkspaceUnit } from './utils.js';
|
||||
import type { WorkspaceUnit } from '../../workspace-unit';
|
||||
|
||||
const WORKSPACE_KEY = 'workspaces';
|
||||
|
||||
@@ -22,21 +22,12 @@ export class LocalProvider extends BaseProvider {
|
||||
super(params);
|
||||
}
|
||||
|
||||
private _storeWorkspaces(workspaces: WorkspaceMeta0[]) {
|
||||
private _storeWorkspaces(workspaceUnits: WorkspaceUnit[]) {
|
||||
storage.setItem(
|
||||
WORKSPACE_KEY,
|
||||
JSON.stringify(
|
||||
workspaces.map(w => {
|
||||
return {
|
||||
id: w.id,
|
||||
name: w.name,
|
||||
avatar: w.avatar,
|
||||
owner: w.owner,
|
||||
published: w.published,
|
||||
memberCount: w.memberCount,
|
||||
provider: w.provider,
|
||||
syncMode: w.syncMode,
|
||||
};
|
||||
workspaceUnits.map(w => {
|
||||
return w.toJSON();
|
||||
})
|
||||
)
|
||||
);
|
||||
@@ -61,20 +52,23 @@ export class LocalProvider extends BaseProvider {
|
||||
return workspace;
|
||||
}
|
||||
|
||||
override loadWorkspaces(): Promise<WorkspaceMeta0[]> {
|
||||
override async loadWorkspaces(): Promise<WorkspaceUnit[]> {
|
||||
const workspaceStr = storage.getItem(WORKSPACE_KEY);
|
||||
let workspaces: WorkspaceMeta0[] = [];
|
||||
if (workspaceStr) {
|
||||
try {
|
||||
workspaces = JSON.parse(workspaceStr) as WorkspaceMeta0[];
|
||||
workspaces.forEach(workspace => {
|
||||
this._workspaces.add(workspace);
|
||||
});
|
||||
const workspaceMetas = JSON.parse(workspaceStr) as WorkspaceMeta0[];
|
||||
const workspaceUnits = await Promise.all(
|
||||
workspaceMetas.map(meta => {
|
||||
return loadWorkspaceUnit(meta);
|
||||
})
|
||||
);
|
||||
this._workspaces.add(workspaceUnits);
|
||||
return workspaceUnits;
|
||||
} catch (error) {
|
||||
this._logger(`Failed to parse workspaces from storage`);
|
||||
}
|
||||
}
|
||||
return Promise.resolve(workspaces);
|
||||
return [];
|
||||
}
|
||||
|
||||
public override async deleteWorkspace(id: string): Promise<void> {
|
||||
@@ -96,10 +90,10 @@ export class LocalProvider extends BaseProvider {
|
||||
this._storeWorkspaces(this._workspaces.list());
|
||||
}
|
||||
|
||||
public override async createWorkspaceInfo(
|
||||
public override async createWorkspace(
|
||||
meta: CreateWorkspaceInfoParams
|
||||
): Promise<WorkspaceMeta0> {
|
||||
const workspaceInfo: WorkspaceMeta0 = {
|
||||
): Promise<WorkspaceUnit | undefined> {
|
||||
const workspaceUnit = await createWorkspaceUnit({
|
||||
name: meta.name,
|
||||
id: uuidv4(),
|
||||
published: false,
|
||||
@@ -108,35 +102,10 @@ export class LocalProvider extends BaseProvider {
|
||||
syncMode: 'core',
|
||||
memberCount: 1,
|
||||
provider: 'local',
|
||||
};
|
||||
return Promise.resolve(workspaceInfo);
|
||||
}
|
||||
|
||||
public override async createWorkspace(
|
||||
blocksuiteWorkspace: BlocksuiteWorkspace,
|
||||
meta: WorkspaceMeta0
|
||||
): Promise<BlocksuiteWorkspace | undefined> {
|
||||
const workspaceId = blocksuiteWorkspace.room;
|
||||
assert(workspaceId, 'Blocksuite Workspace without room(workspaceId).');
|
||||
this._logger('Creating affine workspace');
|
||||
|
||||
const workspaceInfo: WorkspaceMeta0 = {
|
||||
...meta,
|
||||
};
|
||||
|
||||
blocksuiteWorkspace.meta.setName(meta.name);
|
||||
|
||||
if (!meta.avatar) {
|
||||
await setDefaultAvatar(blocksuiteWorkspace);
|
||||
workspaceInfo.avatar = blocksuiteWorkspace.meta.avatar;
|
||||
}
|
||||
|
||||
await initStore(blocksuiteWorkspace);
|
||||
|
||||
this._workspaces.add(workspaceInfo);
|
||||
});
|
||||
this._workspaces.add(workspaceUnit);
|
||||
this._storeWorkspaces(this._workspaces.list());
|
||||
|
||||
return blocksuiteWorkspace;
|
||||
return workspaceUnit;
|
||||
}
|
||||
|
||||
public override async clear(): Promise<void> {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { WorkspaceUnit } from '../../workspace-unit.js';
|
||||
import type { WorkspaceUnitCtorParams } from '../../workspace-unit';
|
||||
import { createBlocksuiteWorkspace } from '../../utils/index.js';
|
||||
import { applyLocalUpdates, writeUpdatesToLocal } from './indexeddb/utils.js';
|
||||
import { setDefaultAvatar } from '../utils.js';
|
||||
|
||||
export const loadWorkspaceUnit = async (params: WorkspaceUnitCtorParams) => {
|
||||
const workspaceUnit = new WorkspaceUnit(params);
|
||||
|
||||
const blocksuiteWorkspace = createBlocksuiteWorkspace(workspaceUnit.id);
|
||||
|
||||
await applyLocalUpdates(blocksuiteWorkspace);
|
||||
|
||||
workspaceUnit.setBlocksuiteWorkspace(blocksuiteWorkspace);
|
||||
|
||||
return workspaceUnit;
|
||||
};
|
||||
|
||||
export const createWorkspaceUnit = async (params: WorkspaceUnitCtorParams) => {
|
||||
const workspaceUnit = new WorkspaceUnit(params);
|
||||
|
||||
const blocksuiteWorkspace = createBlocksuiteWorkspace(workspaceUnit.id);
|
||||
blocksuiteWorkspace.meta.setName(workspaceUnit.name);
|
||||
if (!workspaceUnit.avatar) {
|
||||
await setDefaultAvatar(blocksuiteWorkspace);
|
||||
workspaceUnit.update({ avatar: blocksuiteWorkspace.meta.avatar });
|
||||
}
|
||||
|
||||
await writeUpdatesToLocal(blocksuiteWorkspace);
|
||||
|
||||
workspaceUnit.setBlocksuiteWorkspace(blocksuiteWorkspace);
|
||||
|
||||
return workspaceUnit;
|
||||
};
|
||||
Reference in New Issue
Block a user