feat(core): user data db (#7930)

This commit is contained in:
EYHN
2024-09-11 07:55:37 +00:00
parent 498a69af53
commit d93c3b3719
36 changed files with 1220 additions and 281 deletions

View File

@@ -11,6 +11,7 @@ export * from './modules/global-context';
export * from './modules/lifecycle';
export * from './modules/storage';
export * from './modules/workspace';
export * from './orm';
export * from './storage';
export * from './sync';
export * from './utils';

View File

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

View File

@@ -1,8 +1,10 @@
import { Entity } from '../../../framework';
import type { Table as OrmTable, TableSchemaBuilder } from '../../../orm/core';
import type { Table as OrmTable, TableSchemaBuilder } from '../../../orm';
import type { WorkspaceService } from '../../workspace';
export class Table<Schema extends TableSchemaBuilder> extends Entity<{
export class WorkspaceDBTable<
Schema extends TableSchemaBuilder,
> extends Entity<{
table: OrmTable<Schema>;
storageDocId: string;
}> {

View File

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

View File

@@ -5,7 +5,7 @@ import { createORMClient, YjsDBAdapter } from '../../../orm';
import type { DocStorage } from '../../../sync';
import { ObjectPool } from '../../../utils';
import type { WorkspaceService } from '../../workspace';
import { DB, type DBWithTables } from '../entities/db';
import { WorkspaceDB, type WorkspaceDBWithTables } from '../entities/db';
import { AFFiNE_WORKSPACE_DB_SCHEMA } from '../schema';
import { AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA } from '../schema/schema';
@@ -15,10 +15,10 @@ const WorkspaceUserdataDBClient = createORMClient(
);
export class WorkspaceDBService extends Service {
db: DBWithTables<AFFiNE_WORKSPACE_DB_SCHEMA>;
db: WorkspaceDBWithTables<AFFiNE_WORKSPACE_DB_SCHEMA>;
userdataDBPool = new ObjectPool<
string,
DB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>
WorkspaceDB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>
>({
onDangling() {
return false; // never release
@@ -27,27 +27,30 @@ export class WorkspaceDBService extends Service {
constructor(private readonly workspaceService: WorkspaceService) {
super();
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>;
this.db = this.framework.createEntity(
WorkspaceDB<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 WorkspaceDBWithTables<AFFiNE_WORKSPACE_DB_SCHEMA>;
}
// eslint-disable-next-line @typescript-eslint/ban-types
@@ -55,11 +58,11 @@ export class WorkspaceDBService extends Service {
// __local__ for local workspace
const userdataDb = this.userdataDBPool.get(userId);
if (userdataDb) {
return userdataDb.obj as DBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
return userdataDb.obj as WorkspaceDBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
}
const newDB = this.framework.createEntity(
DB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>,
WorkspaceDB<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>,
{
db: new WorkspaceUserdataDBClient(
new YjsDBAdapter(AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA, {
@@ -84,7 +87,7 @@ export class WorkspaceDBService extends Service {
);
this.userdataDBPool.put(userId, newDB);
return newDB as DBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
return newDB as WorkspaceDBWithTables<AFFiNE_WORKSPACE_USERDATA_DB_SCHEMA>;
}
static isDBDocId(docId: string) {

View File

@@ -1,2 +1,9 @@
export type { DBSchemaBuilder, FieldSchemaBuilder, TableMap } from './core';
export type {
DBSchemaBuilder,
FieldSchemaBuilder,
ORMClient,
Table,
TableMap,
TableSchemaBuilder,
} from './core';
export { createORMClient, f, YjsDBAdapter } from './core';