refactor(core): add all docs properties api (#9484)

This commit is contained in:
EYHN
2025-01-02 10:35:46 +00:00
parent c4e04042b4
commit f2906bc6d0
4 changed files with 86 additions and 3 deletions

View File

@@ -23,7 +23,7 @@ import { DocsStore } from './stores/docs';
export function configureDocModule(framework: Framework) {
framework
.scope(WorkspaceScope)
.service(DocsService, [DocsStore])
.service(DocsService, [DocsStore, DocPropertiesStore])
.store(DocPropertiesStore, [WorkspaceService, WorkspaceDBService])
.store(DocsStore, [WorkspaceService, DocPropertiesStore])
.entity(DocRecord, [DocsStore, DocPropertiesStore])

View File

@@ -3,17 +3,21 @@ import { Unreachable } from '@affine/env/constant';
import type { DocMode } from '@blocksuite/affine/blocks';
import type { DeltaInsert } from '@blocksuite/affine/inline';
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 {
type DocProps,
initDocFromProps,
} from '../../../blocksuite/initialization';
import type { DocProperties } from '../../db';
import type { Doc } from '../entities/doc';
import { DocPropertyList } from '../entities/property-list';
import { DocRecordList } from '../entities/record-list';
import { DocCreated } from '../events';
import { DocScope } from '../scopes/doc';
import type { DocPropertiesStore } from '../stores/doc-properties';
import type { DocsStore } from '../stores/docs';
import { DocService } from './doc';
@@ -30,7 +34,29 @@ export class DocsService extends Service {
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();
}

View File

@@ -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) {
return combineLatest([
this.watchLegacyDocProperties(id).pipe(
@@ -203,6 +225,23 @@ export class DocPropertiesStore extends Store {
?.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) {
return yjsObserveByPath(
this.workspaceService.workspace.rootYDoc.getMap<any>(

View File

@@ -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() {
return yjsObserveByPath(
this.workspaceService.workspace.rootYDoc.getMap('meta'),