mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-26 14:58:55 +08:00
99332228da
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added indexed clock management capabilities for documents, enabling
get, set, and clear operations across Android, iOS, Electron, and web
platforms.
* **Refactor**
* Improved storage architecture to dynamically select platform-specific
implementations (SQLite for Electron, IndexedDB for others).
* **Bug Fixes**
* Enhanced document operations to properly maintain and clean up indexer
synchronization state during document lifecycle changes.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import EventEmitter2 from 'eventemitter2';
|
|
|
|
import type { AwarenessStorage } from './awareness';
|
|
import type { BlobStorage } from './blob';
|
|
import type { BlobSyncStorage } from './blob-sync';
|
|
import type { DocStorage } from './doc';
|
|
import type { DocSyncStorage } from './doc-sync';
|
|
import { DummyAwarenessStorage } from './dummy/awareness';
|
|
import { DummyBlobStorage } from './dummy/blob';
|
|
import { DummyBlobSyncStorage } from './dummy/blob-sync';
|
|
import { DummyDocStorage } from './dummy/doc';
|
|
import { DummyDocSyncStorage } from './dummy/doc-sync';
|
|
import { DummyIndexerStorage } from './dummy/indexer';
|
|
import { DummyIndexerSyncStorage } from './dummy/indexer-sync';
|
|
import type { IndexerStorage } from './indexer';
|
|
import type { IndexerSyncStorage } from './indexer-sync';
|
|
import type { StorageType } from './storage';
|
|
|
|
type Storages =
|
|
| DocStorage
|
|
| BlobStorage
|
|
| BlobSyncStorage
|
|
| DocSyncStorage
|
|
| AwarenessStorage
|
|
| IndexerStorage
|
|
| IndexerSyncStorage;
|
|
|
|
export type SpaceStorageOptions = {
|
|
[K in StorageType]?: Storages & { storageType: K };
|
|
};
|
|
|
|
export class SpaceStorage {
|
|
protected readonly storages: {
|
|
[K in StorageType]: Storages & { storageType: K };
|
|
};
|
|
private readonly event = new EventEmitter2();
|
|
private readonly disposables: Set<() => void> = new Set();
|
|
|
|
constructor(storages: SpaceStorageOptions) {
|
|
this.storages = {
|
|
awareness: storages.awareness ?? new DummyAwarenessStorage(),
|
|
blob: storages.blob ?? new DummyBlobStorage(),
|
|
blobSync: storages.blobSync ?? new DummyBlobSyncStorage(),
|
|
doc: storages.doc ?? new DummyDocStorage(),
|
|
docSync: storages.docSync ?? new DummyDocSyncStorage(),
|
|
indexer: storages.indexer ?? new DummyIndexerStorage(),
|
|
indexerSync: storages.indexerSync ?? new DummyIndexerSyncStorage(),
|
|
};
|
|
}
|
|
|
|
get<T extends StorageType>(type: T): Extract<Storages, { storageType: T }> {
|
|
const storage = this.storages[type];
|
|
|
|
if (!storage) {
|
|
throw new Error(`Storage ${type} not registered.`);
|
|
}
|
|
|
|
return storage as unknown as Extract<Storages, { storageType: T }>;
|
|
}
|
|
|
|
connect() {
|
|
Object.values(this.storages).forEach(storage => {
|
|
storage.connection.connect();
|
|
});
|
|
}
|
|
|
|
disconnect() {
|
|
Object.values(this.storages).forEach(storage => {
|
|
storage.connection.disconnect();
|
|
});
|
|
}
|
|
|
|
async waitForConnected(signal?: AbortSignal) {
|
|
await Promise.all(
|
|
Object.values(this.storages).map(storage =>
|
|
storage.connection.waitForConnected(signal)
|
|
)
|
|
);
|
|
}
|
|
|
|
async destroy() {
|
|
this.disposables.forEach(disposable => disposable());
|
|
this.event.removeAllListeners();
|
|
}
|
|
}
|
|
|
|
export * from './awareness';
|
|
export * from './blob';
|
|
export * from './blob-sync';
|
|
export * from './doc';
|
|
export * from './doc-sync';
|
|
export * from './errors';
|
|
export * from './history';
|
|
export * from './indexer';
|
|
export * from './indexer-sync';
|
|
export * from './storage';
|