feat(core): loading ui for favorite and organize (#7700)

This commit is contained in:
EYHN
2024-08-02 07:17:01 +00:00
parent 94c5effdd5
commit e54be7dc02
15 changed files with 179 additions and 36 deletions

View File

@@ -0,0 +1,28 @@
import { Entity } from '../../../framework';
import type { DBSchemaBuilder, TableMap } from '../../../orm';
import { Table } from './table';
export class DB<Schema extends DBSchemaBuilder> extends Entity<{
db: TableMap<Schema>;
schema: Schema;
storageDocId: (tableName: string) => string;
}> {
readonly db = this.props.db;
constructor() {
super();
Object.entries(this.props.schema).forEach(([tableName]) => {
const table = this.framework.createEntity(Table, {
table: this.db[tableName],
storageDocId: this.props.storageDocId(tableName),
});
Object.defineProperty(this, tableName, {
get: () => table,
});
});
}
}
export type DBWithTables<Schema extends DBSchemaBuilder> = DB<Schema> & {
[K in keyof Schema]: Table<Schema[K]>;
};

View File

@@ -0,0 +1,33 @@
import { Entity } from '../../../framework';
import type { Table as OrmTable, TableSchemaBuilder } from '../../../orm/core';
import type { WorkspaceService } from '../../workspace';
export class Table<Schema extends TableSchemaBuilder> extends Entity<{
table: OrmTable<Schema>;
storageDocId: string;
}> {
readonly table = this.props.table;
constructor(private readonly workspaceService: WorkspaceService) {
super();
}
isSyncing$ = this.workspaceService.workspace.engine.doc
.docState$(this.props.storageDocId)
.map(docState => docState.syncing);
isLoading$ = this.workspaceService.workspace.engine.doc
.docState$(this.props.storageDocId)
.map(docState => docState.loading);
create = this.table.create.bind(this.table);
update = this.table.update.bind(this.table);
get = this.table.get.bind(this.table);
// eslint-disable-next-line rxjs/finnish
get$ = this.table.get$.bind(this.table);
find = this.table.find.bind(this.table);
// eslint-disable-next-line rxjs/finnish
find$ = this.table.find$.bind(this.table);
keys = this.table.keys.bind(this.table);
delete = this.table.delete.bind(this.table);
}

View File

@@ -1,5 +1,7 @@
import type { Framework } from '../../framework';
import { WorkspaceScope, WorkspaceService } from '../workspace';
import { DB } from './entities/db';
import { Table } from './entities/table';
import { WorkspaceDBService } from './services/db';
export { AFFiNE_WORKSPACE_DB_SCHEMA } from './schema';
@@ -8,5 +10,7 @@ export { WorkspaceDBService } from './services/db';
export function configureWorkspaceDBModule(framework: Framework) {
framework
.scope(WorkspaceScope)
.service(WorkspaceDBService, [WorkspaceService]);
.service(WorkspaceDBService, [WorkspaceService])
.entity(DB)
.entity(Table, [WorkspaceService]);
}

View File

@@ -1,9 +1,10 @@
import { Doc as YDoc } from 'yjs';
import { Service } from '../../../framework';
import { createORMClient, type TableMap, YjsDBAdapter } from '../../../orm';
import { createORMClient, YjsDBAdapter } from '../../../orm';
import { ObjectPool } from '../../../utils';
import type { WorkspaceService } from '../../workspace';
import { DB, type DBWithTables } from '../entities/db';
import { AFFiNE_WORKSPACE_DB_SCHEMA } from '../schema';
import { AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA } from '../schema/schema';
@@ -11,11 +12,13 @@ const WorkspaceDBClient = createORMClient(AFFiNE_WORKSPACE_DB_SCHEMA);
const WorkspaceUserdataDBClient = createORMClient(
AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA
);
type WorkspaceUserdataDBClient = InstanceType<typeof WorkspaceUserdataDBClient>;
export class WorkspaceDBService extends Service {
db: TableMap<AFFiNE_WORKSPACE_DB_SCHEMA>;
userdataDBPool = new ObjectPool<string, WorkspaceUserdataDBClient>({
db: DBWithTables<AFFiNE_WORKSPACE_DB_SCHEMA>;
userdataDBPool = new ObjectPool<
string,
DB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>
>({
onDangling() {
return false; // never release
},
@@ -23,19 +26,27 @@ export class WorkspaceDBService extends Service {
constructor(private readonly workspaceService: WorkspaceService) {
super();
this.db = new WorkspaceDBClient(
new YjsDBAdapter(AFFiNE_WORKSPACE_DB_SCHEMA, {
getDoc: guid => {
const ydoc = new YDoc({
// guid format: db${workspaceId}${guid}
guid: `db$${this.workspaceService.workspace.id}$${guid}`,
});
this.workspaceService.workspace.engine.doc.addDoc(ydoc, false);
this.workspaceService.workspace.engine.doc.setPriority(ydoc.guid, 50);
return ydoc;
},
})
);
this.db = this.framework.createEntity(DB<AFFiNE_WORKSPACE_DB_SCHEMA>, {
db: new WorkspaceDBClient(
new YjsDBAdapter(AFFiNE_WORKSPACE_DB_SCHEMA, {
getDoc: guid => {
const ydoc = new YDoc({
// guid format: db${workspaceId}${guid}
guid: `db$${this.workspaceService.workspace.id}$${guid}`,
});
this.workspaceService.workspace.engine.doc.addDoc(ydoc, false);
this.workspaceService.workspace.engine.doc.setPriority(
ydoc.guid,
50
);
return ydoc;
},
})
),
schema: AFFiNE_WORKSPACE_DB_SCHEMA,
storageDocId: tableName =>
`db$${this.workspaceService.workspace.id}$${tableName}`,
}) as DBWithTables<AFFiNE_WORKSPACE_DB_SCHEMA>;
}
// eslint-disable-next-line @typescript-eslint/ban-types
@@ -43,25 +54,36 @@ export class WorkspaceDBService extends Service {
// __local__ for local workspace
const userdataDb = this.userdataDBPool.get(userId);
if (userdataDb) {
return userdataDb.obj;
return userdataDb.obj as DBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
}
const newDB = new WorkspaceUserdataDBClient(
new YjsDBAdapter(AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA, {
getDoc: guid => {
const ydoc = new YDoc({
// guid format: userdata${userId}${workspaceId}${guid}
guid: `userdata$${userId}$${this.workspaceService.workspace.id}$${guid}`,
});
this.workspaceService.workspace.engine.doc.addDoc(ydoc, false);
this.workspaceService.workspace.engine.doc.setPriority(ydoc.guid, 50);
return ydoc;
},
})
const newDB = this.framework.createEntity(
DB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>,
{
db: new WorkspaceUserdataDBClient(
new YjsDBAdapter(AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA, {
getDoc: guid => {
const ydoc = new YDoc({
// guid format: userdata${userId}${workspaceId}${guid}
guid: `userdata$${userId}$${this.workspaceService.workspace.id}$${guid}`,
});
this.workspaceService.workspace.engine.doc.addDoc(ydoc, false);
this.workspaceService.workspace.engine.doc.setPriority(
ydoc.guid,
50
);
return ydoc;
},
})
),
schema: AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA,
storageDocId: tableName =>
`userdata$${userId}$${this.workspaceService.workspace.id}$${tableName}`,
}
);
this.userdataDBPool.put(userId, newDB);
return newDB;
return newDB as DBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
}
static isDBDocId(docId: string) {