Files
AFFiNE-Mirror/packages/common/nbstore/src/worker/ops.ts
T
EYHN aa4874a55c feat(core): use cloud indexer for search (#12899)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added enhanced error handling and user-friendly error messages in
quick search and document search menus.
  - Introduced loading state indicators for search operations.
  - Quick Search now provides explicit error feedback in the UI.

- **Improvements**
- Search and aggregation operations can now prefer remote or local
indexers based on user or system preference.
- Streamlined indexer logic for more consistent and reliable search
experiences.
- Refined error handling in messaging and synchronization layers for
improved stability.
- Enhanced error object handling in messaging for clearer error
propagation.
- Updated cloud workspace storage to always use IndexedDB locally and
CloudIndexer remotely.
- Shifted indexer operations to use synchronized indexer layer for
better consistency.
  - Simplified indexer client by consolidating storage and sync layers.
- Improved error propagation in messaging handlers by wrapping error
objects.
- Updated document search to prioritize remote indexer results by
default.

- **Bug Fixes**
- Improved robustness of search features by handling errors gracefully
and preventing potential runtime issues.

- **Style**
  - Added new styles for displaying error messages in search interfaces.

- **Chores**
- Removed the obsolete "Enable Cloud Indexer" feature flag; cloud
indexer behavior is now always enabled where applicable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-25 02:55:27 +00:00

176 lines
4.4 KiB
TypeScript

import type { AvailableStorageImplementations } from '../impls';
import type {
AggregateResult,
BlobRecord,
DocClock,
DocClocks,
DocDiff,
DocRecord,
DocUpdate,
ListedBlobRecord,
Query,
SearchResult,
StorageType,
} from '../storage';
import type { AwarenessRecord } from '../storage/awareness';
import type { BlobSyncBlobState, BlobSyncState } from '../sync/blob';
import type { DocSyncDocState, DocSyncState } from '../sync/doc';
import type { IndexerDocSyncState, IndexerSyncState } from '../sync/indexer';
type StorageInitOptions = Values<{
[key in keyof AvailableStorageImplementations]: {
name: key;
opts: ConstructorParameters<AvailableStorageImplementations[key]>[0];
};
}>;
export interface StoreInitOptions {
local: { [key in StorageType]?: StorageInitOptions };
remotes: Record<string, { [key in StorageType]?: StorageInitOptions }>;
}
interface GroupedWorkerOps {
docStorage: {
getDoc: [string, DocRecord | null];
getDocDiff: [{ docId: string; state?: Uint8Array }, DocDiff | null];
pushDocUpdate: [{ update: DocUpdate; origin?: string }, DocClock];
getDocTimestamps: [Date | null, DocClocks];
getDocTimestamp: [string, DocClock | null];
deleteDoc: [string, void];
subscribeDocUpdate: [void, { update: DocRecord; origin?: string }];
waitForConnected: [void, void];
};
blobStorage: {
getBlob: [string, BlobRecord | null];
setBlob: [BlobRecord, void];
deleteBlob: [{ key: string; permanently: boolean }, void];
releaseBlobs: [void, void];
listBlobs: [void, ListedBlobRecord[]];
waitForConnected: [void, void];
};
awarenessStorage: {
update: [{ awareness: AwarenessRecord; origin?: string }, void];
subscribeUpdate: [
string,
(
| {
type: 'awareness-update';
awareness: AwarenessRecord;
origin?: string;
}
| { type: 'awareness-collect'; collectId: string }
),
];
collect: [{ collectId: string; awareness: AwarenessRecord }, void];
waitForConnected: [void, void];
};
docSync: {
state: [void, DocSyncState];
docState: [string, DocSyncDocState];
waitForSynced: [string | null, void];
addPriority: [{ docId: string; priority: number }, boolean];
resetSync: [void, void];
};
blobSync: {
state: [void, BlobSyncState];
blobState: [string, BlobSyncBlobState];
downloadBlob: [string, boolean];
uploadBlob: [{ blob: BlobRecord; force?: boolean }, true];
fullDownload: [string | null, void];
};
awarenessSync: {
update: [{ awareness: AwarenessRecord; origin?: string }, void];
subscribeUpdate: [
string,
(
| {
type: 'awareness-update';
awareness: AwarenessRecord;
origin?: string;
}
| { type: 'awareness-collect'; collectId: string }
),
];
collect: [{ collectId: string; awareness: AwarenessRecord }, void];
};
indexerSync: {
state: [void, IndexerSyncState];
docState: [string, IndexerDocSyncState];
addPriority: [{ docId: string; priority: number }, boolean];
waitForCompleted: [void, void];
waitForDocCompleted: [string, void];
search: [
{
table: string;
query: Query<any>;
options?: any;
},
SearchResult<any, any>,
];
aggregate: [
{
table: string;
query: Query<any>;
field: string;
options?: any;
},
AggregateResult<any, any>,
];
subscribeSearch: [
{
table: string;
query: Query<any>;
options?: any;
},
SearchResult<any, any>,
];
subscribeAggregate: [
{
table: string;
query: Query<any>;
field: string;
options?: any;
},
AggregateResult<any, any>,
];
};
}
type Values<T> = T extends { [k in keyof T]: any } ? T[keyof T] : never;
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (
x: infer I
) => void
? I
: never;
export type WorkerOps = UnionToIntersection<
Values<
Values<{
[k in keyof GroupedWorkerOps]: {
[k2 in keyof GroupedWorkerOps[k]]: k2 extends string
? Record<`${k}.${k2}`, GroupedWorkerOps[k][k2]>
: never;
};
}>
>
>;
export type WorkerManagerOps = {
open: [
{
port: MessagePort;
key: string;
closeKey: string;
options: StoreInitOptions;
},
string,
];
close: [string, void];
};