feat: native sync state (#14190)

<!-- 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 -->
This commit is contained in:
DarkSky
2025-12-31 04:09:32 +08:00
committed by GitHub
parent 95ef04f3e0
commit 99332228da
18 changed files with 375 additions and 12 deletions

View File

@@ -1,4 +1,4 @@
import type { CrawlResult } from '@affine/nbstore';
import type { CrawlResult, DocIndexedClock } from '@affine/nbstore';
export interface Blob {
key: string;
@@ -184,7 +184,21 @@ export interface NbStorePlugin {
indexName: string;
docId: string;
query: string;
}) => Promise<{ matches: Array<{ start: number; end: number }> }>;
}) => Promise<{ matches: { start: number; end: number }[] }>;
ftsFlushIndex: (options: { id: string }) => Promise<void>;
ftsIndexVersion: () => Promise<{ indexVersion: number }>;
getDocIndexedClock: (options: {
id: string;
docId: string;
}) => Promise<DocIndexedClock | null>;
setDocIndexedClock: (options: {
id: string;
docId: string;
indexedClock: number;
indexerVersion: number;
}) => Promise<void>;
clearDocIndexedClock: (options: {
id: string;
docId: string;
}) => Promise<void>;
}

View File

@@ -4,7 +4,9 @@ import {
} from '@affine/core/modules/workspace-engine';
import {
type BlobRecord,
type CrawlResult,
type DocClock,
type DocIndexedClock,
type DocRecord,
type ListedBlobRecord,
parseUniversalId,
@@ -321,7 +323,7 @@ export const NbStoreNativeDBApis: NativeDBApis = {
peer,
blobId,
});
return result?.uploadedAt ? new Date(result.uploadedAt) : null;
return result.uploadedAt ? new Date(result.uploadedAt) : null;
},
setBlobUploadedAt: async function (
id: string,
@@ -336,8 +338,11 @@ export const NbStoreNativeDBApis: NativeDBApis = {
uploadedAt: uploadedAt ? uploadedAt.getTime() : null,
});
},
crawlDocData: async function (id: string, docId: string) {
return NbStore.crawlDocData({ id, docId });
crawlDocData: async function (
id: string,
docId: string
): Promise<CrawlResult> {
return await NbStore.crawlDocData({ id, docId });
},
ftsAddDocument: async function (
id: string,
@@ -411,4 +416,29 @@ export const NbStoreNativeDBApis: NativeDBApis = {
ftsIndexVersion: function (): Promise<number> {
return NbStore.ftsIndexVersion().then(res => res.indexVersion);
},
getDocIndexedClock: function (
id: string,
docId: string
): Promise<DocIndexedClock | null> {
return NbStore.getDocIndexedClock({ id, docId });
},
setDocIndexedClock: function (
id: string,
docId: string,
indexedClock: Date,
indexerVersion: number
): Promise<void> {
return NbStore.setDocIndexedClock({
id,
docId,
indexedClock: indexedClock.getTime(),
indexerVersion,
});
},
clearDocIndexedClock: function (id: string, docId: string): Promise<void> {
return NbStore.clearDocIndexedClock({
id,
docId,
});
},
};