mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 10:06:17 +08:00
feat: improve mobile native impl (#14481)
fix #13529 #### PR Dependency Tree * **PR #14481** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Mobile blob caching with file-backed storage for faster loads and reduced network usage * Blob decoding with lazy refresh on token-read failures for improved reliability * Full-text search/indexing exposed to mobile apps * Document sync APIs and peer clock management for robust cross-device sync * **Tests** * Added unit tests covering payload decoding, cache safety, and concurrency * **Dependencies** * Added an LRU cache dependency and a new mobile-shared package for shared mobile logic <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -2,7 +2,7 @@ import type { CrawlResult, DocIndexedClock } from '@affine/nbstore';
|
||||
|
||||
export interface Blob {
|
||||
key: string;
|
||||
// base64 encoded data
|
||||
// base64 encoded data, or "__AFFINE_BLOB_FILE__:<absolutePath>" for large blobs
|
||||
data: string;
|
||||
mime: string;
|
||||
size: number;
|
||||
@@ -41,6 +41,7 @@ export interface NbStorePlugin {
|
||||
pushUpdate: (options: {
|
||||
id: string;
|
||||
docId: string;
|
||||
// base64 encoded data
|
||||
data: string;
|
||||
}) => Promise<{ timestamp: number }>;
|
||||
getDocSnapshot: (options: { id: string; docId: string }) => Promise<
|
||||
@@ -55,6 +56,7 @@ export interface NbStorePlugin {
|
||||
setDocSnapshot: (options: {
|
||||
id: string;
|
||||
docId: string;
|
||||
// base64 encoded data
|
||||
bin: string;
|
||||
timestamp: number;
|
||||
}) => Promise<{ success: boolean }>;
|
||||
|
||||
@@ -2,6 +2,10 @@ import {
|
||||
base64ToUint8Array,
|
||||
uint8ArrayToBase64,
|
||||
} from '@affine/core/modules/workspace-engine';
|
||||
import {
|
||||
decodePayload,
|
||||
MOBILE_BLOB_FILE_PREFIX,
|
||||
} from '@affine/mobile-shared/nbstore/payload';
|
||||
import {
|
||||
type BlobRecord,
|
||||
type CrawlResult,
|
||||
@@ -132,14 +136,23 @@ export const NbStoreNativeDBApis: NativeDBApis = {
|
||||
id,
|
||||
key,
|
||||
});
|
||||
return record
|
||||
? {
|
||||
data: base64ToUint8Array(record.data),
|
||||
key: record.key,
|
||||
mime: record.mime,
|
||||
createdAt: new Date(record.createdAt),
|
||||
}
|
||||
: null;
|
||||
if (!record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let refreshedBlobPromise: ReturnType<typeof NbStore.getBlob> | undefined;
|
||||
|
||||
return {
|
||||
data: await decodePayload(record.data, MOBILE_BLOB_FILE_PREFIX, {
|
||||
onTokenReadFailure: async () => {
|
||||
refreshedBlobPromise ??= NbStore.getBlob({ id, key });
|
||||
return (await refreshedBlobPromise)?.data;
|
||||
},
|
||||
}),
|
||||
key: record.key,
|
||||
mime: record.mime,
|
||||
createdAt: new Date(record.createdAt),
|
||||
};
|
||||
},
|
||||
setBlob: async function (id: string, blob: BlobRecord): Promise<void> {
|
||||
await NbStore.setBlob({
|
||||
|
||||
Reference in New Issue
Block a user