mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-03 02:20:19 +08:00
feat(nbstore): improve nbstore (#9512)
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
import type { Observable } from 'rxjs';
|
||||
import { combineLatest, map } from 'rxjs';
|
||||
import { combineLatest, map, of } from 'rxjs';
|
||||
|
||||
import type { DocStorage, SyncStorage } from '../../storage';
|
||||
import { DummyDocStorage } from '../../storage/dummy/doc';
|
||||
import { DummySyncStorage } from '../../storage/dummy/sync';
|
||||
import { MANUALLY_STOP } from '../../utils/throw-if-aborted';
|
||||
import type { PeerStorageOptions } from '../types';
|
||||
import { DocSyncPeer } from './peer';
|
||||
|
||||
export interface DocSyncState {
|
||||
total: number;
|
||||
syncing: number;
|
||||
synced: boolean;
|
||||
retrying: boolean;
|
||||
errorMessage: string | null;
|
||||
}
|
||||
|
||||
export interface DocSyncDocState {
|
||||
synced: boolean;
|
||||
syncing: boolean;
|
||||
retrying: boolean;
|
||||
errorMessage: string | null;
|
||||
@@ -24,43 +30,70 @@ export interface DocSync {
|
||||
}
|
||||
|
||||
export class DocSyncImpl implements DocSync {
|
||||
private readonly peers: DocSyncPeer[] = this.remotes.map(
|
||||
remote => new DocSyncPeer(this.local, this.sync, remote)
|
||||
private readonly peers: DocSyncPeer[] = Object.entries(
|
||||
this.storages.remotes
|
||||
).map(
|
||||
([peerId, remote]) =>
|
||||
new DocSyncPeer(peerId, this.storages.local, this.sync, remote)
|
||||
);
|
||||
private abort: AbortController | null = null;
|
||||
|
||||
readonly state$: Observable<DocSyncState> = combineLatest(
|
||||
this.peers.map(peer => peer.peerState$)
|
||||
).pipe(
|
||||
map(allPeers => ({
|
||||
total: allPeers.reduce((acc, peer) => acc + peer.total, 0),
|
||||
syncing: allPeers.reduce((acc, peer) => acc + peer.syncing, 0),
|
||||
retrying: allPeers.some(peer => peer.retrying),
|
||||
errorMessage:
|
||||
allPeers.find(peer => peer.errorMessage)?.errorMessage ?? null,
|
||||
}))
|
||||
);
|
||||
|
||||
constructor(
|
||||
readonly local: DocStorage,
|
||||
readonly sync: SyncStorage,
|
||||
readonly remotes: DocStorage[]
|
||||
) {}
|
||||
|
||||
docState$(docId: string): Observable<DocSyncDocState> {
|
||||
return combineLatest(this.peers.map(peer => peer.docState$(docId))).pipe(
|
||||
get state$() {
|
||||
return combineLatest(this.peers.map(peer => peer.peerState$)).pipe(
|
||||
map(allPeers => ({
|
||||
total: allPeers.reduce((acc, peer) => Math.max(acc, peer.total), 0),
|
||||
syncing: allPeers.reduce((acc, peer) => Math.max(acc, peer.syncing), 0),
|
||||
synced: allPeers.every(peer => peer.synced),
|
||||
retrying: allPeers.some(peer => peer.retrying),
|
||||
errorMessage:
|
||||
allPeers.find(peer => peer.errorMessage)?.errorMessage ?? null,
|
||||
retrying: allPeers.some(peer => peer.retrying),
|
||||
syncing: allPeers.some(peer => peer.syncing),
|
||||
}))
|
||||
) as Observable<DocSyncState>;
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly storages: PeerStorageOptions<DocStorage>,
|
||||
readonly sync: SyncStorage
|
||||
) {}
|
||||
|
||||
/**
|
||||
* for testing
|
||||
*/
|
||||
static get dummy() {
|
||||
return new DocSyncImpl(
|
||||
{
|
||||
local: new DummyDocStorage(),
|
||||
remotes: {},
|
||||
},
|
||||
new DummySyncStorage()
|
||||
);
|
||||
}
|
||||
|
||||
docState$(docId: string): Observable<DocSyncDocState> {
|
||||
if (this.peers.length === 0) {
|
||||
return of({
|
||||
errorMessage: null,
|
||||
retrying: false,
|
||||
syncing: false,
|
||||
synced: true,
|
||||
});
|
||||
}
|
||||
return combineLatest(this.peers.map(peer => peer.docState$(docId))).pipe(
|
||||
map(allPeers => {
|
||||
return {
|
||||
errorMessage:
|
||||
allPeers.find(peer => peer.errorMessage)?.errorMessage ?? null,
|
||||
retrying: allPeers.some(peer => peer.retrying),
|
||||
syncing: allPeers.some(peer => peer.syncing),
|
||||
synced: allPeers.every(peer => peer.synced),
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.abort) {
|
||||
this.abort.abort();
|
||||
this.abort.abort(MANUALLY_STOP);
|
||||
}
|
||||
const abort = new AbortController();
|
||||
this.abort = abort;
|
||||
|
||||
Reference in New Issue
Block a user