feat(nbstore): rename SyncStorage to DocSyncStorage (#10751)

This commit is contained in:
EYHN
2025-03-14 06:25:26 +00:00
parent 92effd9b51
commit f3ef9c4415
19 changed files with 90 additions and 79 deletions

View File

@@ -6,7 +6,7 @@ import { Doc as YDoc, encodeStateAsUpdate } from 'yjs';
import { import {
IndexedDBBlobStorage, IndexedDBBlobStorage,
IndexedDBDocStorage, IndexedDBDocStorage,
IndexedDBSyncStorage, IndexedDBDocSyncStorage,
} from '../impls/idb'; } from '../impls/idb';
import { SpaceStorage } from '../storage'; import { SpaceStorage } from '../storage';
import { Sync } from '../sync'; import { Sync } from '../sync';
@@ -23,7 +23,7 @@ test('doc', async () => {
type: 'workspace', type: 'workspace',
}); });
const peerASync = new IndexedDBSyncStorage({ const peerASync = new IndexedDBDocSyncStorage({
id: 'ws1', id: 'ws1',
flavour: 'a', flavour: 'a',
type: 'workspace', type: 'workspace',
@@ -42,7 +42,7 @@ test('doc', async () => {
const peerA = new SpaceStorage({ const peerA = new SpaceStorage({
doc: peerADoc, doc: peerADoc,
sync: peerASync, docSync: peerASync,
}); });
const peerB = new SpaceStorage({ const peerB = new SpaceStorage({
doc: peerBDoc, doc: peerBDoc,

View File

@@ -1,9 +1,13 @@
import { share } from '../../connection'; import { share } from '../../connection';
import { type DocClock, type DocClocks, SyncStorageBase } from '../../storage'; import {
type DocClock,
type DocClocks,
DocSyncStorageBase,
} from '../../storage';
import { IDBConnection, type IDBConnectionOptions } from './db'; import { IDBConnection, type IDBConnectionOptions } from './db';
export class IndexedDBSyncStorage extends SyncStorageBase { export class IndexedDBDocSyncStorage extends DocSyncStorageBase {
static readonly identifier = 'IndexedDBSyncStorage'; static readonly identifier = 'IndexedDBDocSyncStorage';
constructor(private readonly options: IDBConnectionOptions) { constructor(private readonly options: IDBConnectionOptions) {
super(); super();

View File

@@ -1,14 +1,14 @@
import type { StorageConstructor } from '..'; import type { StorageConstructor } from '..';
import { IndexedDBBlobStorage } from './blob'; import { IndexedDBBlobStorage } from './blob';
import { IndexedDBDocStorage } from './doc'; import { IndexedDBDocStorage } from './doc';
import { IndexedDBSyncStorage } from './sync'; import { IndexedDBDocSyncStorage } from './doc-sync';
export * from './blob'; export * from './blob';
export * from './doc'; export * from './doc';
export * from './sync'; export * from './doc-sync';
export const idbStorages = [ export const idbStorages = [
IndexedDBDocStorage, IndexedDBDocStorage,
IndexedDBBlobStorage, IndexedDBBlobStorage,
IndexedDBSyncStorage, IndexedDBDocSyncStorage,
] satisfies StorageConstructor[]; ] satisfies StorageConstructor[];

View File

@@ -1,9 +1,9 @@
import { share } from '../../connection'; import { share } from '../../connection';
import { type DocClock, SyncStorageBase } from '../../storage'; import { type DocClock, DocSyncStorageBase } from '../../storage';
import { NativeDBConnection, type SqliteNativeDBOptions } from './db'; import { NativeDBConnection, type SqliteNativeDBOptions } from './db';
export class SqliteSyncStorage extends SyncStorageBase { export class SqliteDocSyncStorage extends DocSyncStorageBase {
static readonly identifier = 'SqliteSyncStorage'; static readonly identifier = 'SqliteDocSyncStorage';
override connection = share(new NativeDBConnection(this.options)); override connection = share(new NativeDBConnection(this.options));

View File

@@ -1,15 +1,15 @@
import type { StorageConstructor } from '..'; import type { StorageConstructor } from '..';
import { SqliteBlobStorage } from './blob'; import { SqliteBlobStorage } from './blob';
import { SqliteDocStorage } from './doc'; import { SqliteDocStorage } from './doc';
import { SqliteSyncStorage } from './sync'; import { SqliteDocSyncStorage } from './doc-sync';
export * from './blob'; export * from './blob';
export { bindNativeDBApis, type NativeDBApis } from './db'; export { bindNativeDBApis, type NativeDBApis } from './db';
export * from './doc'; export * from './doc';
export * from './sync'; export * from './doc-sync';
export const sqliteStorages = [ export const sqliteStorages = [
SqliteDocStorage, SqliteDocStorage,
SqliteBlobStorage, SqliteBlobStorage,
SqliteSyncStorage, SqliteDocSyncStorage,
] satisfies StorageConstructor[]; ] satisfies StorageConstructor[];

View File

@@ -2,8 +2,8 @@ import type { Connection } from '../connection';
import type { DocClock, DocClocks } from './doc'; import type { DocClock, DocClocks } from './doc';
import { type Storage } from './storage'; import { type Storage } from './storage';
export interface SyncStorage extends Storage { export interface DocSyncStorage extends Storage {
readonly storageType: 'sync'; readonly storageType: 'docSync';
getPeerRemoteClock(peer: string, docId: string): Promise<DocClock | null>; getPeerRemoteClock(peer: string, docId: string): Promise<DocClock | null>;
getPeerRemoteClocks(peer: string): Promise<DocClocks>; getPeerRemoteClocks(peer: string): Promise<DocClocks>;
@@ -20,8 +20,8 @@ export interface SyncStorage extends Storage {
clearClocks(): Promise<void>; clearClocks(): Promise<void>;
} }
export abstract class SyncStorageBase implements SyncStorage { export abstract class DocSyncStorageBase implements DocSyncStorage {
readonly storageType = 'sync'; readonly storageType = 'docSync';
abstract readonly connection: Connection; abstract readonly connection: Connection;
abstract getPeerRemoteClock( abstract getPeerRemoteClock(

View File

@@ -1,8 +1,8 @@
import { DummyConnection } from '../../connection'; import { DummyConnection } from '../../connection';
import type { DocClock, DocClocks } from '../doc'; import type { DocClock, DocClocks } from '../doc';
import { SyncStorageBase } from '../sync'; import { DocSyncStorageBase } from '../doc-sync';
export class DummySyncStorage extends SyncStorageBase { export class DummyDocSyncStorage extends DocSyncStorageBase {
override getPeerRemoteClock( override getPeerRemoteClock(
_peer: string, _peer: string,
_docId: string _docId: string

View File

@@ -9,6 +9,7 @@ import {
} from '../doc'; } from '../doc';
export class DummyDocStorage implements DocStorage { export class DummyDocStorage implements DocStorage {
spaceId = '';
readonly storageType = 'doc'; readonly storageType = 'doc';
readonly isReadonly = true; readonly isReadonly = true;
getDoc(_docId: string): Promise<DocRecord | null> { getDoc(_docId: string): Promise<DocRecord | null> {

View File

@@ -3,14 +3,14 @@ import EventEmitter2 from 'eventemitter2';
import type { AwarenessStorage } from './awareness'; import type { AwarenessStorage } from './awareness';
import type { BlobStorage } from './blob'; import type { BlobStorage } from './blob';
import type { DocStorage } from './doc'; import type { DocStorage } from './doc';
import type { DocSyncStorage } from './doc-sync';
import { DummyAwarenessStorage } from './dummy/awareness'; import { DummyAwarenessStorage } from './dummy/awareness';
import { DummyBlobStorage } from './dummy/blob'; import { DummyBlobStorage } from './dummy/blob';
import { DummyDocStorage } from './dummy/doc'; import { DummyDocStorage } from './dummy/doc';
import { DummySyncStorage } from './dummy/sync'; import { DummyDocSyncStorage } from './dummy/doc-sync';
import type { StorageType } from './storage'; import type { StorageType } from './storage';
import type { SyncStorage } from './sync';
type Storages = DocStorage | BlobStorage | SyncStorage | AwarenessStorage; type Storages = DocStorage | BlobStorage | DocSyncStorage | AwarenessStorage;
export type SpaceStorageOptions = { export type SpaceStorageOptions = {
[K in StorageType]?: Storages & { storageType: K }; [K in StorageType]?: Storages & { storageType: K };
@@ -28,7 +28,7 @@ export class SpaceStorage {
awareness: storages.awareness ?? new DummyAwarenessStorage(), awareness: storages.awareness ?? new DummyAwarenessStorage(),
blob: storages.blob ?? new DummyBlobStorage(), blob: storages.blob ?? new DummyBlobStorage(),
doc: storages.doc ?? new DummyDocStorage(), doc: storages.doc ?? new DummyDocStorage(),
sync: storages.sync ?? new DummySyncStorage(), ['docSync']: storages['docSync'] ?? new DummyDocSyncStorage(),
}; };
} }
@@ -71,7 +71,7 @@ export class SpaceStorage {
export * from './awareness'; export * from './awareness';
export * from './blob'; export * from './blob';
export * from './doc'; export * from './doc';
export * from './doc-sync';
export * from './errors'; export * from './errors';
export * from './history'; export * from './history';
export * from './storage'; export * from './storage';
export * from './sync';

View File

@@ -1,6 +1,6 @@
import type { Connection } from '../connection'; import type { Connection } from '../connection';
export type StorageType = 'blob' | 'doc' | 'sync' | 'awareness'; export type StorageType = 'blob' | 'doc' | 'docSync' | 'awareness';
export interface Storage { export interface Storage {
readonly storageType: StorageType; readonly storageType: StorageType;

View File

@@ -1,9 +1,9 @@
import type { Observable } from 'rxjs'; import type { Observable } from 'rxjs';
import { combineLatest, map, of, ReplaySubject, share } from 'rxjs'; import { combineLatest, map, of, ReplaySubject, share } from 'rxjs';
import type { DocStorage, SyncStorage } from '../../storage'; import type { DocStorage, DocSyncStorage } from '../../storage';
import { DummyDocStorage } from '../../storage/dummy/doc'; import { DummyDocStorage } from '../../storage/dummy/doc';
import { DummySyncStorage } from '../../storage/dummy/sync'; import { DummyDocSyncStorage } from '../../storage/dummy/doc-sync';
import { MANUALLY_STOP } from '../../utils/throw-if-aborted'; import { MANUALLY_STOP } from '../../utils/throw-if-aborted';
import type { PeerStorageOptions } from '../types'; import type { PeerStorageOptions } from '../types';
import { DocSyncPeer } from './peer'; import { DocSyncPeer } from './peer';
@@ -68,7 +68,7 @@ export class DocSyncImpl implements DocSync {
constructor( constructor(
readonly storages: PeerStorageOptions<DocStorage>, readonly storages: PeerStorageOptions<DocStorage>,
readonly sync: SyncStorage readonly sync: DocSyncStorage
) {} ) {}
/** /**
@@ -80,7 +80,7 @@ export class DocSyncImpl implements DocSync {
local: new DummyDocStorage(), local: new DummyDocStorage(),
remotes: {}, remotes: {},
}, },
new DummySyncStorage() new DummyDocSyncStorage()
); );
} }

View File

@@ -3,7 +3,7 @@ import { nanoid } from 'nanoid';
import { Observable, ReplaySubject, share, Subject } from 'rxjs'; import { Observable, ReplaySubject, share, Subject } from 'rxjs';
import { diffUpdate, encodeStateVectorFromUpdate, mergeUpdates } from 'yjs'; import { diffUpdate, encodeStateVectorFromUpdate, mergeUpdates } from 'yjs';
import type { DocStorage, SyncStorage } from '../../storage'; import type { DocStorage, DocSyncStorage } from '../../storage';
import { AsyncPriorityQueue } from '../../utils/async-priority-queue'; import { AsyncPriorityQueue } from '../../utils/async-priority-queue';
import { ClockMap } from '../../utils/clock'; import { ClockMap } from '../../utils/clock';
import { isEmptyUpdate } from '../../utils/is-empty-update'; import { isEmptyUpdate } from '../../utils/is-empty-update';
@@ -147,7 +147,7 @@ export class DocSyncPeer {
constructor( constructor(
readonly peerId: string, readonly peerId: string,
readonly local: DocStorage, readonly local: DocStorage,
readonly syncMetadata: SyncStorage, readonly syncMetadata: DocSyncStorage,
readonly remote: DocStorage, readonly remote: DocStorage,
readonly options: DocSyncPeerOptions = {} readonly options: DocSyncPeerOptions = {}
) {} ) {}

View File

@@ -23,7 +23,7 @@ export class Sync {
constructor(readonly storages: PeerStorageOptions<SpaceStorage>) { constructor(readonly storages: PeerStorageOptions<SpaceStorage>) {
const doc = storages.local.get('doc'); const doc = storages.local.get('doc');
const blob = storages.local.get('blob'); const blob = storages.local.get('blob');
const sync = storages.local.get('sync'); const docSync = storages.local.get('docSync');
const awareness = storages.local.get('awareness'); const awareness = storages.local.get('awareness');
this.doc = new DocSyncImpl( this.doc = new DocSyncImpl(
@@ -36,7 +36,7 @@ export class Sync {
]) ])
), ),
}, },
sync docSync
); );
this.blob = new BlobSyncImpl({ this.blob = new BlobSyncImpl({
local: blob, local: blob,

View File

@@ -45,8 +45,8 @@ class StoreConsumer {
return this.ensureSync.blob; return this.ensureSync.blob;
} }
get syncStorage() { get docSyncStorage() {
return this.ensureLocal.get('sync'); return this.ensureLocal.get('docSync');
} }
get awarenessStorage() { get awarenessStorage() {
@@ -170,25 +170,25 @@ class StoreConsumer {
this.blobStorage.delete(key, permanently), this.blobStorage.delete(key, permanently),
'blobStorage.releaseBlobs': () => this.blobStorage.release(), 'blobStorage.releaseBlobs': () => this.blobStorage.release(),
'blobStorage.listBlobs': () => this.blobStorage.list(), 'blobStorage.listBlobs': () => this.blobStorage.list(),
'syncStorage.clearClocks': () => this.syncStorage.clearClocks(), 'docSyncStorage.clearClocks': () => this.docSyncStorage.clearClocks(),
'syncStorage.getPeerPulledRemoteClock': ({ peer, docId }) => 'docSyncStorage.getPeerPulledRemoteClock': ({ peer, docId }) =>
this.syncStorage.getPeerPulledRemoteClock(peer, docId), this.docSyncStorage.getPeerPulledRemoteClock(peer, docId),
'syncStorage.getPeerPulledRemoteClocks': ({ peer }) => 'docSyncStorage.getPeerPulledRemoteClocks': ({ peer }) =>
this.syncStorage.getPeerPulledRemoteClocks(peer), this.docSyncStorage.getPeerPulledRemoteClocks(peer),
'syncStorage.setPeerPulledRemoteClock': ({ peer, clock }) => 'docSyncStorage.setPeerPulledRemoteClock': ({ peer, clock }) =>
this.syncStorage.setPeerPulledRemoteClock(peer, clock), this.docSyncStorage.setPeerPulledRemoteClock(peer, clock),
'syncStorage.getPeerRemoteClock': ({ peer, docId }) => 'docSyncStorage.getPeerRemoteClock': ({ peer, docId }) =>
this.syncStorage.getPeerRemoteClock(peer, docId), this.docSyncStorage.getPeerRemoteClock(peer, docId),
'syncStorage.getPeerRemoteClocks': ({ peer }) => 'docSyncStorage.getPeerRemoteClocks': ({ peer }) =>
this.syncStorage.getPeerRemoteClocks(peer), this.docSyncStorage.getPeerRemoteClocks(peer),
'syncStorage.setPeerRemoteClock': ({ peer, clock }) => 'docSyncStorage.setPeerRemoteClock': ({ peer, clock }) =>
this.syncStorage.setPeerRemoteClock(peer, clock), this.docSyncStorage.setPeerRemoteClock(peer, clock),
'syncStorage.getPeerPushedClock': ({ peer, docId }) => 'docSyncStorage.getPeerPushedClock': ({ peer, docId }) =>
this.syncStorage.getPeerPushedClock(peer, docId), this.docSyncStorage.getPeerPushedClock(peer, docId),
'syncStorage.getPeerPushedClocks': ({ peer }) => 'docSyncStorage.getPeerPushedClocks': ({ peer }) =>
this.syncStorage.getPeerPushedClocks(peer), this.docSyncStorage.getPeerPushedClocks(peer),
'syncStorage.setPeerPushedClock': ({ peer, clock }) => 'docSyncStorage.setPeerPushedClock': ({ peer, clock }) =>
this.syncStorage.setPeerPushedClock(peer, clock), this.docSyncStorage.setPeerPushedClock(peer, clock),
'awarenessStorage.update': ({ awareness, origin }) => 'awarenessStorage.update': ({ awareness, origin }) =>
this.awarenessStorage.update(awareness, origin), this.awarenessStorage.update(awareness, origin),
'awarenessStorage.subscribeUpdate': docId => 'awarenessStorage.subscribeUpdate': docId =>

View File

@@ -45,7 +45,7 @@ interface GroupedWorkerOps {
listBlobs: [void, ListedBlobRecord[]]; listBlobs: [void, ListedBlobRecord[]];
}; };
syncStorage: { docSyncStorage: {
getPeerPulledRemoteClocks: [{ peer: string }, DocClocks]; getPeerPulledRemoteClocks: [{ peer: string }, DocClocks];
getPeerPulledRemoteClock: [ getPeerPulledRemoteClock: [
{ peer: string; docId: string }, { peer: string; docId: string },

View File

@@ -23,7 +23,10 @@ const cache = createEmotionCache();
let storeManagerClient: StoreManagerClient; let storeManagerClient: StoreManagerClient;
if (window.SharedWorker) { if (
window.SharedWorker &&
localStorage.getItem('disableSharedWorker') !== 'true'
) {
const worker = new SharedWorker( const worker = new SharedWorker(
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url), new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url),
{ name: 'affine-shared-worker' } { name: 'affine-shared-worker' }

View File

@@ -1,5 +1,8 @@
import { IndexedDBDocStorage, IndexedDBSyncStorage } from '@affine/nbstore/idb'; import {
import { SqliteDocStorage, SqliteSyncStorage } from '@affine/nbstore/sqlite'; IndexedDBDocStorage,
IndexedDBDocSyncStorage,
} from '@affine/nbstore/idb';
import { SqliteDocStorage, SqliteDocSyncStorage } from '@affine/nbstore/sqlite';
import type { StoreClient } from '@affine/nbstore/worker/client'; import type { StoreClient } from '@affine/nbstore/worker/client';
import { Entity } from '@toeverything/infra'; import { Entity } from '@toeverything/infra';
@@ -16,10 +19,10 @@ export class UserDBEngine extends Entity<{
BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS
? SqliteDocStorage ? SqliteDocStorage
: IndexedDBDocStorage; : IndexedDBDocStorage;
SyncStorageType = DocSyncStorageType =
BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS
? SqliteSyncStorage ? SqliteDocSyncStorage
: IndexedDBSyncStorage; : IndexedDBDocSyncStorage;
canGracefulStop() { canGracefulStop() {
// TODO(@eyhn): Implement this // TODO(@eyhn): Implement this
@@ -44,8 +47,8 @@ export class UserDBEngine extends Entity<{
type: 'userspace', type: 'userspace',
}, },
}, },
sync: { docSync: {
name: this.SyncStorageType.identifier, name: this.DocSyncStorageType.identifier,
opts: { opts: {
id: `${serverService.server.id}:` + this.userId, id: `${serverService.server.id}:` + this.userId,
type: 'userspace', type: 'userspace',

View File

@@ -14,7 +14,7 @@ import { CloudBlobStorage, StaticCloudDocStorage } from '@affine/nbstore/cloud';
import { import {
IndexedDBBlobStorage, IndexedDBBlobStorage,
IndexedDBDocStorage, IndexedDBDocStorage,
IndexedDBSyncStorage, IndexedDBDocSyncStorage,
} from '@affine/nbstore/idb'; } from '@affine/nbstore/idb';
import { import {
IndexedDBV1BlobStorage, IndexedDBV1BlobStorage,
@@ -23,7 +23,7 @@ import {
import { import {
SqliteBlobStorage, SqliteBlobStorage,
SqliteDocStorage, SqliteDocStorage,
SqliteSyncStorage, SqliteDocSyncStorage,
} from '@affine/nbstore/sqlite'; } from '@affine/nbstore/sqlite';
import { import {
SqliteV1BlobStorage, SqliteV1BlobStorage,
@@ -111,10 +111,10 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
: BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb : BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb
? IndexedDBV1BlobStorage ? IndexedDBV1BlobStorage
: undefined; : undefined;
SyncStorageType = DocSyncStorageType =
BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS
? SqliteSyncStorage ? SqliteDocSyncStorage
: IndexedDBSyncStorage; : IndexedDBDocSyncStorage;
async deleteWorkspace(id: string): Promise<void> { async deleteWorkspace(id: string): Promise<void> {
await this.graphqlService.gql({ await this.graphqlService.gql({
@@ -431,8 +431,8 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
id: workspaceId, id: workspaceId,
}, },
}, },
sync: { docSync: {
name: this.SyncStorageType.identifier, name: this.DocSyncStorageType.identifier,
opts: { opts: {
flavour: this.flavour, flavour: this.flavour,
type: 'workspace', type: 'workspace',

View File

@@ -8,7 +8,7 @@ import {
import { import {
IndexedDBBlobStorage, IndexedDBBlobStorage,
IndexedDBDocStorage, IndexedDBDocStorage,
IndexedDBSyncStorage, IndexedDBDocSyncStorage,
} from '@affine/nbstore/idb'; } from '@affine/nbstore/idb';
import { import {
IndexedDBV1BlobStorage, IndexedDBV1BlobStorage,
@@ -17,7 +17,7 @@ import {
import { import {
SqliteBlobStorage, SqliteBlobStorage,
SqliteDocStorage, SqliteDocStorage,
SqliteSyncStorage, SqliteDocSyncStorage,
} from '@affine/nbstore/sqlite'; } from '@affine/nbstore/sqlite';
import { import {
SqliteV1BlobStorage, SqliteV1BlobStorage,
@@ -97,10 +97,10 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
: BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb : BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb
? IndexedDBV1BlobStorage ? IndexedDBV1BlobStorage
: undefined; : undefined;
SyncStorageType = DocSyncStorageType =
BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS
? SqliteSyncStorage ? SqliteDocSyncStorage
: IndexedDBSyncStorage; : IndexedDBDocSyncStorage;
async deleteWorkspace(id: string): Promise<void> { async deleteWorkspace(id: string): Promise<void> {
setLocalWorkspaceIds(ids => ids.filter(x => x !== id)); setLocalWorkspaceIds(ids => ids.filter(x => x !== id));
@@ -321,8 +321,8 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
id: workspaceId, id: workspaceId,
}, },
}, },
sync: { docSync: {
name: this.SyncStorageType.identifier, name: this.DocSyncStorageType.identifier,
opts: { opts: {
flavour: this.flavour, flavour: this.flavour,
type: 'workspace', type: 'workspace',