mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
feat(nbstore): add blob sync storage (#10752)
This commit is contained in:
@@ -176,6 +176,7 @@ class WorkerBlobStorage implements BlobStorage {
|
||||
constructor(private readonly client: OpClient<WorkerOps>) {}
|
||||
|
||||
readonly storageType = 'blob';
|
||||
readonly isReadonly = false;
|
||||
|
||||
get(key: string, _signal?: AbortSignal): Promise<BlobRecord | null> {
|
||||
return this.client.call('blobStorage.getBlob', key);
|
||||
@@ -233,47 +234,38 @@ class WorkerBlobSync implements BlobSync {
|
||||
get state$() {
|
||||
return this.client.ob$('blobSync.state');
|
||||
}
|
||||
setMaxBlobSize(size: number): void {
|
||||
this.client.call('blobSync.setMaxBlobSize', size).catch(err => {
|
||||
console.error('error setting max blob size', err);
|
||||
});
|
||||
blobState$(blobId: string) {
|
||||
return this.client.ob$('blobSync.blobState', blobId);
|
||||
}
|
||||
onReachedMaxBlobSize(cb: (byteSize: number) => void): () => void {
|
||||
const subscription = this.client
|
||||
.ob$('blobSync.onReachedMaxBlobSize')
|
||||
.subscribe(byteSize => {
|
||||
cb(byteSize);
|
||||
});
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}
|
||||
downloadBlob(
|
||||
blobId: string,
|
||||
_signal?: AbortSignal
|
||||
): Promise<BlobRecord | null> {
|
||||
|
||||
downloadBlob(blobId: string): Promise<void> {
|
||||
return this.client.call('blobSync.downloadBlob', blobId);
|
||||
}
|
||||
uploadBlob(blob: BlobRecord, _signal?: AbortSignal): Promise<void> {
|
||||
uploadBlob(blob: BlobRecord): Promise<void> {
|
||||
return this.client.call('blobSync.uploadBlob', blob);
|
||||
}
|
||||
fullDownload(signal?: AbortSignal): Promise<void> {
|
||||
const download = this.client.call('blobSync.fullDownload');
|
||||
fullDownload(peerId?: string, signal?: AbortSignal): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const abortListener = () => {
|
||||
reject(signal?.reason);
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
|
||||
signal?.addEventListener('abort', () => {
|
||||
download.cancel();
|
||||
signal?.addEventListener('abort', abortListener);
|
||||
|
||||
const subscription = this.client
|
||||
.ob$('blobSync.fullDownload', peerId ?? null)
|
||||
.subscribe({
|
||||
next() {
|
||||
signal?.removeEventListener('abort', abortListener);
|
||||
resolve();
|
||||
},
|
||||
error(err) {
|
||||
signal?.removeEventListener('abort', abortListener);
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return download;
|
||||
}
|
||||
fullUpload(signal?: AbortSignal): Promise<void> {
|
||||
const upload = this.client.call('blobSync.fullUpload');
|
||||
|
||||
signal?.addEventListener('abort', () => {
|
||||
upload.cancel();
|
||||
});
|
||||
|
||||
return upload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,25 +170,6 @@ class StoreConsumer {
|
||||
this.blobStorage.delete(key, permanently),
|
||||
'blobStorage.releaseBlobs': () => this.blobStorage.release(),
|
||||
'blobStorage.listBlobs': () => this.blobStorage.list(),
|
||||
'docSyncStorage.clearClocks': () => this.docSyncStorage.clearClocks(),
|
||||
'docSyncStorage.getPeerPulledRemoteClock': ({ peer, docId }) =>
|
||||
this.docSyncStorage.getPeerPulledRemoteClock(peer, docId),
|
||||
'docSyncStorage.getPeerPulledRemoteClocks': ({ peer }) =>
|
||||
this.docSyncStorage.getPeerPulledRemoteClocks(peer),
|
||||
'docSyncStorage.setPeerPulledRemoteClock': ({ peer, clock }) =>
|
||||
this.docSyncStorage.setPeerPulledRemoteClock(peer, clock),
|
||||
'docSyncStorage.getPeerRemoteClock': ({ peer, docId }) =>
|
||||
this.docSyncStorage.getPeerRemoteClock(peer, docId),
|
||||
'docSyncStorage.getPeerRemoteClocks': ({ peer }) =>
|
||||
this.docSyncStorage.getPeerRemoteClocks(peer),
|
||||
'docSyncStorage.setPeerRemoteClock': ({ peer, clock }) =>
|
||||
this.docSyncStorage.setPeerRemoteClock(peer, clock),
|
||||
'docSyncStorage.getPeerPushedClock': ({ peer, docId }) =>
|
||||
this.docSyncStorage.getPeerPushedClock(peer, docId),
|
||||
'docSyncStorage.getPeerPushedClocks': ({ peer }) =>
|
||||
this.docSyncStorage.getPeerPushedClocks(peer),
|
||||
'docSyncStorage.setPeerPushedClock': ({ peer, clock }) =>
|
||||
this.docSyncStorage.setPeerPushedClock(peer, clock),
|
||||
'awarenessStorage.update': ({ awareness, origin }) =>
|
||||
this.awarenessStorage.update(awareness, origin),
|
||||
'awarenessStorage.subscribeUpdate': docId =>
|
||||
@@ -232,20 +213,23 @@ class StoreConsumer {
|
||||
return () => undo();
|
||||
}),
|
||||
'docSync.resetSync': () => this.docSync.resetSync(),
|
||||
'blobSync.state': () => this.blobSync.state$,
|
||||
'blobSync.blobState': blobId => this.blobSync.blobState$(blobId),
|
||||
'blobSync.downloadBlob': key => this.blobSync.downloadBlob(key),
|
||||
'blobSync.uploadBlob': blob => this.blobSync.uploadBlob(blob),
|
||||
'blobSync.fullDownload': (_, { signal }) =>
|
||||
this.blobSync.fullDownload(signal),
|
||||
'blobSync.fullUpload': (_, { signal }) =>
|
||||
this.blobSync.fullUpload(signal),
|
||||
'blobSync.state': () => this.blobSync.state$,
|
||||
'blobSync.setMaxBlobSize': size => this.blobSync.setMaxBlobSize(size),
|
||||
'blobSync.onReachedMaxBlobSize': () =>
|
||||
'blobSync.fullDownload': peerId =>
|
||||
new Observable(subscriber => {
|
||||
const undo = this.blobSync.onReachedMaxBlobSize(byteSize => {
|
||||
subscriber.next(byteSize);
|
||||
});
|
||||
return () => undo();
|
||||
const abortController = new AbortController();
|
||||
this.blobSync
|
||||
.fullDownload(peerId ?? undefined, abortController.signal)
|
||||
.then(() => {
|
||||
subscriber.next();
|
||||
subscriber.complete();
|
||||
})
|
||||
.catch(error => {
|
||||
subscriber.error(error);
|
||||
});
|
||||
return () => abortController.abort(MANUALLY_STOP);
|
||||
}),
|
||||
'awarenessSync.update': ({ awareness, origin }) =>
|
||||
this.awarenessSync.update(awareness, origin),
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {
|
||||
StorageType,
|
||||
} from '../storage';
|
||||
import type { AwarenessRecord } from '../storage/awareness';
|
||||
import type { BlobSyncState } from '../sync/blob';
|
||||
import type { BlobSyncBlobState, BlobSyncState } from '../sync/blob';
|
||||
import type { DocSyncDocState, DocSyncState } from '../sync/doc';
|
||||
|
||||
type StorageInitOptions = Values<{
|
||||
@@ -45,22 +45,6 @@ interface GroupedWorkerOps {
|
||||
listBlobs: [void, ListedBlobRecord[]];
|
||||
};
|
||||
|
||||
docSyncStorage: {
|
||||
getPeerPulledRemoteClocks: [{ peer: string }, DocClocks];
|
||||
getPeerPulledRemoteClock: [
|
||||
{ peer: string; docId: string },
|
||||
DocClock | null,
|
||||
];
|
||||
setPeerPulledRemoteClock: [{ peer: string; clock: DocClock }, void];
|
||||
getPeerRemoteClocks: [{ peer: string }, DocClocks];
|
||||
getPeerRemoteClock: [{ peer: string; docId: string }, DocClock | null];
|
||||
setPeerRemoteClock: [{ peer: string; clock: DocClock }, void];
|
||||
getPeerPushedClocks: [{ peer: string }, DocClocks];
|
||||
getPeerPushedClock: [{ peer: string; docId: string }, DocClock | null];
|
||||
setPeerPushedClock: [{ peer: string; clock: DocClock }, void];
|
||||
clearClocks: [void, void];
|
||||
};
|
||||
|
||||
awarenessStorage: {
|
||||
update: [{ awareness: AwarenessRecord; origin?: string }, void];
|
||||
subscribeUpdate: [
|
||||
@@ -85,13 +69,11 @@ interface GroupedWorkerOps {
|
||||
};
|
||||
|
||||
blobSync: {
|
||||
downloadBlob: [string, BlobRecord | null];
|
||||
uploadBlob: [BlobRecord, void];
|
||||
fullDownload: [void, void];
|
||||
fullUpload: [void, void];
|
||||
setMaxBlobSize: [number, void];
|
||||
onReachedMaxBlobSize: [void, number];
|
||||
state: [void, BlobSyncState];
|
||||
blobState: [string, BlobSyncBlobState];
|
||||
downloadBlob: [string, void];
|
||||
uploadBlob: [BlobRecord, void];
|
||||
fullDownload: [string | null, void];
|
||||
};
|
||||
|
||||
awarenessSync: {
|
||||
|
||||
Reference in New Issue
Block a user