diff --git a/packages/common/infra/src/modules/doc/entities/record-list.ts b/packages/common/infra/src/modules/doc/entities/record-list.ts index 2cdfcb556f..df5e52daa1 100644 --- a/packages/common/infra/src/modules/doc/entities/record-list.ts +++ b/packages/common/infra/src/modules/doc/entities/record-list.ts @@ -13,23 +13,28 @@ export class DocRecordList extends Entity { private readonly pool = new Map(); - public readonly docs$ = LiveData.from( + public readonly docsMap$ = LiveData.from>( this.store.watchDocIds().pipe( - map(ids => - ids.map(id => { - const exists = this.pool.get(id); - if (exists) { - return exists; - } - const record = this.framework.createEntity(DocRecord, { id }); - this.pool.set(id, record); - return record; - }) + map( + ids => + new Map( + ids.map(id => { + const exists = this.pool.get(id); + if (exists) { + return [id, exists]; + } + const record = this.framework.createEntity(DocRecord, { id }); + this.pool.set(id, record); + return [id, record]; + }) + ) ) ), - [] + new Map() ); + public readonly docs$ = this.docsMap$.selector(d => Array.from(d.values())); + public readonly trashDocs$ = LiveData.from( this.store.watchTrashDocIds().pipe( map(ids => @@ -53,7 +58,7 @@ export class DocRecordList extends Entity { ); public doc$(id: string) { - return this.docs$.map(record => record.find(record => record.id === id)); + return this.docsMap$.selector(map => map.get(id)); } public setPrimaryMode(id: string, mode: DocMode) { diff --git a/packages/common/infra/src/modules/doc/stores/docs.ts b/packages/common/infra/src/modules/doc/stores/docs.ts index 99854744c5..4df3619377 100644 --- a/packages/common/infra/src/modules/doc/stores/docs.ts +++ b/packages/common/infra/src/modules/doc/stores/docs.ts @@ -32,7 +32,7 @@ export class DocsStore extends Store { switchMap(yjsObserve), map(meta => { if (meta instanceof YArray) { - return meta.map(v => v.get('id')); + return meta.map(v => v.get('id') as string); } else { return []; } @@ -59,6 +59,7 @@ export class DocsStore extends Store { } watchDocMeta(id: string) { + let docMetaIndexCache = -1; return yjsObserveByPath( this.workspaceService.workspace.rootYDoc.getMap('meta'), 'pages' @@ -66,13 +67,23 @@ export class DocsStore extends Store { switchMap(yjsObserve), map(meta => { if (meta instanceof YArray) { - let docMetaYMap = null as YMap | null; - meta.forEach(doc => { - if (doc.get('id') === id) { - docMetaYMap = doc; + if (docMetaIndexCache >= 0) { + const doc = meta.get(docMetaIndexCache); + if (doc && doc.get('id') === id) { + return doc as YMap; } - }); - return docMetaYMap; + } + + // meta is YArray, `for-of` is faster then `for` + let i = 0; + for (const doc of meta) { + if (doc && doc.get('id') === id) { + docMetaIndexCache = i; + return doc as YMap; + } + i++; + } + return null; } else { return null; }