refactor(core): add all docs properties api (#9484)
This commit is contained in:
@@ -23,7 +23,7 @@ import { DocsStore } from './stores/docs';
|
|||||||
export function configureDocModule(framework: Framework) {
|
export function configureDocModule(framework: Framework) {
|
||||||
framework
|
framework
|
||||||
.scope(WorkspaceScope)
|
.scope(WorkspaceScope)
|
||||||
.service(DocsService, [DocsStore])
|
.service(DocsService, [DocsStore, DocPropertiesStore])
|
||||||
.store(DocPropertiesStore, [WorkspaceService, WorkspaceDBService])
|
.store(DocPropertiesStore, [WorkspaceService, WorkspaceDBService])
|
||||||
.store(DocsStore, [WorkspaceService, DocPropertiesStore])
|
.store(DocsStore, [WorkspaceService, DocPropertiesStore])
|
||||||
.entity(DocRecord, [DocsStore, DocPropertiesStore])
|
.entity(DocRecord, [DocsStore, DocPropertiesStore])
|
||||||
|
|||||||
@@ -3,17 +3,21 @@ import { Unreachable } from '@affine/env/constant';
|
|||||||
import type { DocMode } from '@blocksuite/affine/blocks';
|
import type { DocMode } from '@blocksuite/affine/blocks';
|
||||||
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
||||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||||
import { ObjectPool, Service } from '@toeverything/infra';
|
import { LiveData, ObjectPool, Service } from '@toeverything/infra';
|
||||||
|
import { omitBy } from 'lodash-es';
|
||||||
|
import { combineLatest, map } from 'rxjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type DocProps,
|
type DocProps,
|
||||||
initDocFromProps,
|
initDocFromProps,
|
||||||
} from '../../../blocksuite/initialization';
|
} from '../../../blocksuite/initialization';
|
||||||
|
import type { DocProperties } from '../../db';
|
||||||
import type { Doc } from '../entities/doc';
|
import type { Doc } from '../entities/doc';
|
||||||
import { DocPropertyList } from '../entities/property-list';
|
import { DocPropertyList } from '../entities/property-list';
|
||||||
import { DocRecordList } from '../entities/record-list';
|
import { DocRecordList } from '../entities/record-list';
|
||||||
import { DocCreated } from '../events';
|
import { DocCreated } from '../events';
|
||||||
import { DocScope } from '../scopes/doc';
|
import { DocScope } from '../scopes/doc';
|
||||||
|
import type { DocPropertiesStore } from '../stores/doc-properties';
|
||||||
import type { DocsStore } from '../stores/docs';
|
import type { DocsStore } from '../stores/docs';
|
||||||
import { DocService } from './doc';
|
import { DocService } from './doc';
|
||||||
|
|
||||||
@@ -30,7 +34,29 @@ export class DocsService extends Service {
|
|||||||
|
|
||||||
propertyList = this.framework.createEntity(DocPropertyList);
|
propertyList = this.framework.createEntity(DocPropertyList);
|
||||||
|
|
||||||
constructor(private readonly store: DocsStore) {
|
/**
|
||||||
|
* used for search doc by properties, for convenience of search, all non-exist doc or trash doc have been filtered
|
||||||
|
*/
|
||||||
|
allDocProperties$: LiveData<Record<string, DocProperties>> = LiveData.from(
|
||||||
|
combineLatest([
|
||||||
|
this.docPropertiesStore.watchAllDocProperties(),
|
||||||
|
this.store.watchNonTrashDocIds(),
|
||||||
|
]).pipe(
|
||||||
|
map(([properties, docIds]) => {
|
||||||
|
const allIds = new Set(docIds);
|
||||||
|
return omitBy(
|
||||||
|
properties as Record<string, DocProperties>,
|
||||||
|
(_, id) => !allIds.has(id)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly store: DocsStore,
|
||||||
|
private readonly docPropertiesStore: DocPropertiesStore
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,28 @@ export class DocPropertiesStore extends Store {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchAllDocProperties() {
|
||||||
|
const allDocProperties$ = this.dbService.db.docProperties.find$();
|
||||||
|
const allLegacyDocProperties$ = this.watchAllLegacyDocProperties();
|
||||||
|
|
||||||
|
return combineLatest([allDocProperties$, allLegacyDocProperties$]).pipe(
|
||||||
|
map(([db, legacy]) => {
|
||||||
|
const map = new Map(db.map(i => [i.id, i]));
|
||||||
|
const allIds = new Set([...map.keys(), ...Object.keys(legacy ?? {})]);
|
||||||
|
|
||||||
|
const result = {} as Record<string, Record<string, any>>;
|
||||||
|
|
||||||
|
for (const id of allIds) {
|
||||||
|
result[id] = {
|
||||||
|
...this.upgradeLegacyDocProperties(legacy?.[id]),
|
||||||
|
...omitBy(map.get(id), isNil),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
watchDocProperties(id: string) {
|
watchDocProperties(id: string) {
|
||||||
return combineLatest([
|
return combineLatest([
|
||||||
this.watchLegacyDocProperties(id).pipe(
|
this.watchLegacyDocProperties(id).pipe(
|
||||||
@@ -203,6 +225,23 @@ export class DocPropertiesStore extends Store {
|
|||||||
?.toJSON() as LegacyDocProperties | undefined;
|
?.toJSON() as LegacyDocProperties | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private watchAllLegacyDocProperties() {
|
||||||
|
return yjsObserveByPath(
|
||||||
|
this.workspaceService.workspace.rootYDoc.getMap<any>(
|
||||||
|
'affine:workspace-properties'
|
||||||
|
),
|
||||||
|
`pageProperties`
|
||||||
|
).pipe(
|
||||||
|
switchMap(yjsObserveDeep),
|
||||||
|
map(
|
||||||
|
p =>
|
||||||
|
(p instanceof YAbstractType ? p.toJSON() : p) as
|
||||||
|
| { [docId: string]: LegacyDocProperties }
|
||||||
|
| undefined
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private watchLegacyDocProperties(id: string) {
|
private watchLegacyDocProperties(id: string) {
|
||||||
return yjsObserveByPath(
|
return yjsObserveByPath(
|
||||||
this.workspaceService.workspace.rootYDoc.getMap<any>(
|
this.workspaceService.workspace.rootYDoc.getMap<any>(
|
||||||
|
|||||||
@@ -44,6 +44,24 @@ export class DocsStore extends Store {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchNonTrashDocIds() {
|
||||||
|
return yjsObserveByPath(
|
||||||
|
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
||||||
|
'pages'
|
||||||
|
).pipe(
|
||||||
|
switchMap(yjsObserveDeep),
|
||||||
|
map(meta => {
|
||||||
|
if (meta instanceof YArray) {
|
||||||
|
return meta
|
||||||
|
.map(v => (v.get('trash') ? null : v.get('id')))
|
||||||
|
.filter(Boolean) as string[];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
watchTrashDocIds() {
|
watchTrashDocIds() {
|
||||||
return yjsObserveByPath(
|
return yjsObserveByPath(
|
||||||
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
||||||
|
|||||||
Reference in New Issue
Block a user