mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
128 lines
3.1 KiB
TypeScript
128 lines
3.1 KiB
TypeScript
import { Observable } from 'lib0/observable';
|
|
import type { WorkspaceInfo, WorkspaceMeta } from './types';
|
|
|
|
export interface WorkspaceMetaCollectionScope {
|
|
get: (workspaceId: string) => WorkspaceInfo | undefined;
|
|
list: () => WorkspaceInfo[];
|
|
add: (workspace: WorkspaceInfo) => void;
|
|
remove: (workspaceId: string) => boolean;
|
|
clear: () => void;
|
|
update: (workspaceId: string, workspaceMeta: Partial<WorkspaceMeta>) => void;
|
|
}
|
|
|
|
export interface WorkspaceMetaCollectionChangeEvent {
|
|
added?: WorkspaceInfo;
|
|
deleted?: WorkspaceInfo;
|
|
updated?: WorkspaceInfo;
|
|
}
|
|
|
|
export class WorkspaceMetaCollection extends Observable<'change'> {
|
|
private _workspacesMap = new Map<string, WorkspaceInfo>();
|
|
|
|
get workspaces(): WorkspaceInfo[] {
|
|
return Array.from(this._workspacesMap.values());
|
|
}
|
|
|
|
find(workspaceId: string) {
|
|
return this._workspacesMap.get(workspaceId);
|
|
}
|
|
|
|
createScope(): WorkspaceMetaCollectionScope {
|
|
const scopedWorkspaceIds = new Set<string>();
|
|
|
|
const get = (workspaceId: string) => {
|
|
if (!scopedWorkspaceIds.has(workspaceId)) {
|
|
return;
|
|
}
|
|
return this._workspacesMap.get(workspaceId);
|
|
};
|
|
|
|
const add = (workspace: WorkspaceInfo) => {
|
|
if (this._workspacesMap.has(workspace.id)) {
|
|
throw new Error(`Duplicate workspace id.`);
|
|
}
|
|
this._workspacesMap.set(workspace.id, workspace);
|
|
scopedWorkspaceIds.add(workspace.id);
|
|
|
|
this.emit('change', [
|
|
{
|
|
added: workspace,
|
|
} as WorkspaceMetaCollectionChangeEvent,
|
|
]);
|
|
};
|
|
|
|
const remove = (workspaceId: string) => {
|
|
if (!scopedWorkspaceIds.has(workspaceId)) {
|
|
return true;
|
|
}
|
|
|
|
const workspace = this._workspacesMap.get(workspaceId);
|
|
if (workspace) {
|
|
const ret = this._workspacesMap.delete(workspaceId);
|
|
// If deletion failed, return.
|
|
if (!ret) {
|
|
return ret;
|
|
}
|
|
|
|
scopedWorkspaceIds.delete(workspaceId);
|
|
|
|
this.emit('change', [
|
|
{
|
|
deleted: workspace,
|
|
} as WorkspaceMetaCollectionChangeEvent,
|
|
]);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
const clear = () => {
|
|
scopedWorkspaceIds.forEach(id => {
|
|
remove(id);
|
|
});
|
|
};
|
|
|
|
const update = (
|
|
workspaceId: string,
|
|
workspaceMeta: Partial<WorkspaceMeta>
|
|
) => {
|
|
if (!scopedWorkspaceIds.has(workspaceId)) {
|
|
return true;
|
|
}
|
|
|
|
const workspace = this._workspacesMap.get(workspaceId);
|
|
if (!workspace) {
|
|
return true;
|
|
}
|
|
|
|
this._workspacesMap.set(workspaceId, { ...workspace, ...workspaceMeta });
|
|
|
|
this.emit('change', [
|
|
{
|
|
updated: this._workspacesMap.get(workspaceId),
|
|
} as WorkspaceMetaCollectionChangeEvent,
|
|
]);
|
|
};
|
|
|
|
// TODO: need to optimize
|
|
const list = () => {
|
|
const workspaces: WorkspaceInfo[] = [];
|
|
scopedWorkspaceIds.forEach(id => {
|
|
const workspace = this._workspacesMap.get(id);
|
|
if (workspace) {
|
|
workspaces.push(workspace);
|
|
}
|
|
});
|
|
return workspaces;
|
|
};
|
|
|
|
return {
|
|
get,
|
|
list,
|
|
add,
|
|
remove,
|
|
clear,
|
|
update,
|
|
};
|
|
}
|
|
}
|