fix: create workspace optimize

This commit is contained in:
alt0
2023-01-10 11:23:00 +08:00
parent 0a4a9fcdb1
commit d3012de9d6
5 changed files with 73 additions and 37 deletions

View File

@@ -7,8 +7,8 @@ import { AffineProvider } from './provider';
import type { WorkspaceMeta } from './types'; import type { WorkspaceMeta } from './types';
import assert from 'assert'; import assert from 'assert';
import { getLogger } from './logger'; import { getLogger } from './logger';
import { BlockSchema } from '@blocksuite/blocks/models';
import { applyUpdate, encodeStateAsUpdate } from 'yjs'; import { applyUpdate, encodeStateAsUpdate } from 'yjs';
import { createBlocksuiteWorkspace } from './utils/index.js';
/** /**
* @class DataCenter * @class DataCenter
@@ -89,7 +89,13 @@ export class DataCenter {
'There is no provider. You should add provider first.' 'There is no provider. You should add provider first.'
); );
const workspace = await this._mainProvider.createWorkspace(workspaceMeta); const workspaceId = await this._mainProvider.createWorkspaceId(
workspaceMeta
);
const workspace = createBlocksuiteWorkspace(workspaceId);
await this._mainProvider.createWorkspace(workspace, workspaceMeta);
return workspace; return workspace;
} }
@@ -109,14 +115,12 @@ export class DataCenter {
* get a new workspace only has room id * get a new workspace only has room id
* @param {string} workspaceId workspace id * @param {string} workspaceId workspace id
*/ */
private _getWorkspace(workspaceId: string) { private _getBlocksuiteWorkspace(workspaceId: string) {
const workspaceInfo = this._workspaces.find(workspaceId); const workspaceInfo = this._workspaces.find(workspaceId);
assert(workspaceInfo, 'Workspace not found'); assert(workspaceInfo, 'Workspace not found');
return ( return (
this._workspaceInstances.get(workspaceId) || this._workspaceInstances.get(workspaceId) ||
new BlocksuiteWorkspace({ createBlocksuiteWorkspace(workspaceId)
room: workspaceId,
}).register(BlockSchema)
); );
} }
@@ -155,7 +159,7 @@ export class DataCenter {
const provider = this.providerMap.get(workspaceInfo.provider); const provider = this.providerMap.get(workspaceInfo.provider);
assert(provider, `provide '${workspaceInfo.provider}' is not registered`); assert(provider, `provide '${workspaceInfo.provider}' is not registered`);
this._logger(`Loading ${workspaceInfo.provider} workspace: `, workspaceId); this._logger(`Loading ${workspaceInfo.provider} workspace: `, workspaceId);
const workspace = this._getWorkspace(workspaceId); const workspace = this._getBlocksuiteWorkspace(workspaceId);
this._workspaceInstances.set(workspaceId, workspace); this._workspaceInstances.set(workspaceId, workspace);
return await provider.warpWorkspace(workspace); return await provider.warpWorkspace(workspace);
} }
@@ -288,11 +292,17 @@ export class DataCenter {
const newProvider = this.providerMap.get(providerId); const newProvider = this.providerMap.get(providerId);
assert(newProvider, `provide '${providerId}' is not registered`); assert(newProvider, `provide '${providerId}' is not registered`);
this._logger(`create ${providerId} workspace: `, workspaceInfo.name); this._logger(`create ${providerId} workspace: `, workspaceInfo.name);
// TODO optimize this function const newWorkspaceId = await newProvider.createWorkspaceId({
const newWorkspace = await newProvider.createWorkspace({
name: workspaceInfo.name, name: workspaceInfo.name,
avatar: workspaceInfo.avatar, avatar: workspaceInfo.avatar,
}); });
const newWorkspace = createBlocksuiteWorkspace(newWorkspaceId);
// TODO optimize this function
await newProvider.createWorkspace(newWorkspace, {
name: workspaceInfo.name,
avatar: workspaceInfo.avatar,
});
assert(newWorkspace, 'Create workspace failed'); assert(newWorkspace, 'Create workspace failed');
this._logger( this._logger(
`update workspace data from ${workspaceInfo.provider} to ${providerId}` `update workspace data from ${workspaceInfo.provider} to ${providerId}`

View File

@@ -58,17 +58,24 @@ export class AffineProvider extends BaseProvider {
} }
} }
override async warpWorkspace(workspace: BlocksuiteWorkspace) { private async _applyCloudUpdates(blocksuiteWorkspace: BlocksuiteWorkspace) {
const { doc, room } = workspace; const { doc, room: workspaceId } = blocksuiteWorkspace;
assert(room); assert(workspaceId, 'Blocksuite Workspace without room(workspaceId).');
this.linkLocal(workspace); const updates = await this._apis.downloadWorkspace(workspaceId);
const updates = await this._apis.downloadWorkspace(room);
if (updates && updates.byteLength) { if (updates && updates.byteLength) {
await new Promise(resolve => { await new Promise(resolve => {
doc.once('update', resolve); doc.once('update', resolve);
applyUpdate(doc, new Uint8Array(updates)); BlocksuiteWorkspace.Y.applyUpdate(doc, new Uint8Array(updates));
}); });
} }
}
override async warpWorkspace(workspace: BlocksuiteWorkspace) {
await this._applyCloudUpdates(workspace);
const { doc, room } = workspace;
assert(room);
this.linkLocal(workspace);
let ws = this._wsMap.get(room); let ws = this._wsMap.get(room);
if (!ws) { if (!ws) {
ws = new WebsocketProvider('/', room, doc); ws = new WebsocketProvider('/', room, doc);
@@ -247,23 +254,29 @@ export class AffineProvider extends BaseProvider {
// return workspace; // return workspace;
} }
public override async createWorkspace( public override async createWorkspaceId(
meta: WorkspaceMeta meta: WorkspaceMeta
): Promise<BlocksuiteWorkspace | undefined> { ): Promise<string> {
assert(meta.name, 'Workspace name is required');
const { id } = await this._apis.createWorkspace( const { id } = await this._apis.createWorkspace(
meta as Required<WorkspaceMeta> meta as Required<WorkspaceMeta>
); );
return id;
}
public override async createWorkspace(
blocksuiteWorkspace: BlocksuiteWorkspace,
meta: WorkspaceMeta
): Promise<BlocksuiteWorkspace | undefined> {
const workspaceId = blocksuiteWorkspace.room;
assert(workspaceId, 'Blocksuite Workspace without room(workspaceId).');
this._logger('Creating affine workspace'); this._logger('Creating affine workspace');
const nw = new BlocksuiteWorkspace({
room: id, this._applyCloudUpdates(blocksuiteWorkspace);
}).register(BlockSchema); this.linkLocal(blocksuiteWorkspace);
nw.meta.setName(meta.name);
this.linkLocal(nw);
const workspaceInfo: WorkspaceInfo = { const workspaceInfo: WorkspaceInfo = {
name: meta.name, name: meta.name,
id, id: workspaceId,
isPublish: false, isPublish: false,
avatar: '', avatar: '',
owner: undefined, owner: undefined,
@@ -272,20 +285,20 @@ export class AffineProvider extends BaseProvider {
provider: 'affine', provider: 'affine',
}; };
if (!meta.avatar) { if (!blocksuiteWorkspace.meta.avatar) {
// set default avatar // set default avatar
const blob = await getDefaultHeadImgBlob(meta.name); const blob = await getDefaultHeadImgBlob(meta.name);
const blobStorage = await nw.blobs; const blobStorage = await blocksuiteWorkspace.blobs;
assert(blobStorage, 'No blob storage'); assert(blobStorage, 'No blob storage');
const blobId = await blobStorage.set(blob); const blobId = await blobStorage.set(blob);
const avatar = await blobStorage.get(blobId); const avatar = await blobStorage.get(blobId);
if (avatar) { if (avatar) {
nw.meta.setAvatar(avatar); blocksuiteWorkspace.meta.setAvatar(avatar);
workspaceInfo.avatar = avatar; workspaceInfo.avatar = avatar;
} }
} }
this._workspaces.add(workspaceInfo); this._workspaces.add(workspaceInfo);
return nw; return blocksuiteWorkspace;
} }
public override async publish(id: string, isPublish: boolean): Promise<void> { public override async publish(id: string, isPublish: boolean): Promise<void> {

View File

@@ -1,4 +1,4 @@
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store'; import { Workspace as BlocksuiteWorkspace, uuidv4 } from '@blocksuite/store';
import { Logger, User, WorkspaceInfo, WorkspaceMeta } from '../types'; import { Logger, User, WorkspaceInfo, WorkspaceMeta } from '../types';
import type { WorkspacesScope } from '../workspaces'; import type { WorkspacesScope } from '../workspaces';
@@ -28,6 +28,10 @@ export class BaseProvider {
return; return;
} }
public async createWorkspaceId(meta: WorkspaceMeta): Promise<string> {
return uuidv4();
}
/** /**
* auth provider * auth provider
*/ */
@@ -155,10 +159,10 @@ export class BaseProvider {
* @param {WorkspaceMeta} meta * @param {WorkspaceMeta} meta
*/ */
public async createWorkspace( public async createWorkspace(
blocksuiteWorkspace: BlocksuiteWorkspace,
meta: WorkspaceMeta meta: WorkspaceMeta
): Promise<BlocksuiteWorkspace | undefined> { ): Promise<BlocksuiteWorkspace | undefined> {
meta; return blocksuiteWorkspace;
return;
} }
/** /**

View File

@@ -76,6 +76,7 @@ export class LocalProvider extends BaseProvider {
} }
public override async createWorkspace( public override async createWorkspace(
blocksuiteWorkspace: BlocksuiteWorkspace,
meta: WorkspaceMeta meta: WorkspaceMeta
): Promise<BlocksuiteWorkspace | undefined> { ): Promise<BlocksuiteWorkspace | undefined> {
assert(meta.name, 'Workspace name is required'); assert(meta.name, 'Workspace name is required');
@@ -92,18 +93,17 @@ export class LocalProvider extends BaseProvider {
provider: 'local', provider: 'local',
}; };
const workspace = new BlocksuiteWorkspace({ room: workspaceInfo.id }); this.linkLocal(blocksuiteWorkspace);
this.linkLocal(workspace); blocksuiteWorkspace.meta.setName(meta.name);
workspace.meta.setName(meta.name);
if (!meta.avatar) { if (!meta.avatar) {
// set default avatar // set default avatar
const blob = await getDefaultHeadImgBlob(meta.name); const blob = await getDefaultHeadImgBlob(meta.name);
const blobStorage = await workspace.blobs; const blobStorage = await blocksuiteWorkspace.blobs;
assert(blobStorage, 'No blob storage'); assert(blobStorage, 'No blob storage');
const blobId = await blobStorage.set(blob); const blobId = await blobStorage.set(blob);
const avatar = await blobStorage.get(blobId); const avatar = await blobStorage.get(blobId);
if (avatar) { if (avatar) {
workspace.meta.setAvatar(avatar); blocksuiteWorkspace.meta.setAvatar(avatar);
workspaceInfo.avatar = avatar; workspaceInfo.avatar = avatar;
} }
} }
@@ -111,7 +111,7 @@ export class LocalProvider extends BaseProvider {
this._workspaces.add(workspaceInfo); this._workspaces.add(workspaceInfo);
this._storeWorkspaces(this._workspaces.list()); this._storeWorkspaces(this._workspaces.list());
return workspace; return blocksuiteWorkspace;
} }
public override async clear(): Promise<void> { public override async clear(): Promise<void> {

View File

@@ -1,3 +1,12 @@
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
import { BlockSchema } from '@blocksuite/blocks/models';
export const createBlocksuiteWorkspace = (workspaceId: string) => {
return new BlocksuiteWorkspace({
room: workspaceId,
}).register(BlockSchema);
};
const DefaultHeadImgColors = [ const DefaultHeadImgColors = [
['#C6F2F3', '#0C6066'], ['#C6F2F3', '#0C6066'],
['#FFF5AB', '#896406'], ['#FFF5AB', '#896406'],