From f927ed7be2b5b2970d7e946ebfbc1e704257db47 Mon Sep 17 00:00:00 2001 From: Kallyn Gowdy Date: Tue, 29 Oct 2024 17:13:17 -0400 Subject: [PATCH] feat: Make YjsPartition utilize YjsSharedDocument --- .../documents/SharedDocumentConfig.ts | 3 +- src/aux-common/documents/YjsSharedDocument.ts | 2 +- .../partitions/AuxPartitionConfig.ts | 11 +- src/aux-common/partitions/YjsPartition.ts | 123 ++---------------- 4 files changed, 19 insertions(+), 120 deletions(-) diff --git a/src/aux-common/documents/SharedDocumentConfig.ts b/src/aux-common/documents/SharedDocumentConfig.ts index 860c93c23f..a2d6cc75c6 100644 --- a/src/aux-common/documents/SharedDocumentConfig.ts +++ b/src/aux-common/documents/SharedDocumentConfig.ts @@ -6,8 +6,9 @@ import { RemoteCausalRepoProtocol } from '../partitions/AuxPartitionConfig'; export interface SharedDocumentConfig { /** * The branch of the document to load. + * If omitted, then local persistence will not be supported. */ - branch: string; + branch?: string; /** * The options for local persistence of the document. diff --git a/src/aux-common/documents/YjsSharedDocument.ts b/src/aux-common/documents/YjsSharedDocument.ts index 5bae5cdbd1..6fcba95c4a 100644 --- a/src/aux-common/documents/YjsSharedDocument.ts +++ b/src/aux-common/documents/YjsSharedDocument.ts @@ -205,7 +205,7 @@ export class YjsSharedDocument implements SharedDocument { async init(): Promise {} connect(): void { - if (this._persistence?.saveToIndexedDb) { + if (this._persistence?.saveToIndexedDb && this._branch) { console.log('[YjsPartition] Using IndexedDB persistence'); this._indexeddb = new YjsIndexedDBPersistence( this._branch, diff --git a/src/aux-common/partitions/AuxPartitionConfig.ts b/src/aux-common/partitions/AuxPartitionConfig.ts index cdf3dadbcd..4b6da639f9 100644 --- a/src/aux-common/partitions/AuxPartitionConfig.ts +++ b/src/aux-common/partitions/AuxPartitionConfig.ts @@ -236,6 +236,12 @@ export interface PartitionRemoteEvents { export interface YjsPartitionConfig extends PartitionConfigBase { type: 'yjs'; + /** + * The branch to load. + * If omitted, then local persistence will not be supported. + */ + branch?: string; + /** * The options for local persistence for the partition. */ @@ -245,11 +251,6 @@ export interface YjsPartitionConfig extends PartitionConfigBase { */ saveToIndexedDb: boolean; - /** - * The database that updates should be saved under. - */ - database: string; - /** * The encryption key that should be used. */ diff --git a/src/aux-common/partitions/YjsPartition.ts b/src/aux-common/partitions/YjsPartition.ts index 4ca7c080ac..8249aa8f23 100644 --- a/src/aux-common/partitions/YjsPartition.ts +++ b/src/aux-common/partitions/YjsPartition.ts @@ -76,8 +76,8 @@ import { StatusUpdate, VersionVector, } from '../common'; -import { YjsIndexedDBPersistence } from '../yjs/YjsIndexedDBPersistence'; import { fromByteArray, toByteArray } from 'base64-js'; +import { YjsSharedDocument } from '../documents/YjsSharedDocument'; const APPLY_UPDATES_TO_INST_TRANSACTION_ORIGIN = '__apply_updates_to_inst'; @@ -95,27 +95,16 @@ export function createYjsPartition(config: PartitionConfig): YjsPartition { type MapValue = Text | object | number | boolean; type TagsMap = Map; -export class YjsPartitionImpl implements YjsPartition { - protected _onVersionUpdated: BehaviorSubject; - - protected _onError = new Subject(); - protected _onEvents = new Subject(); - protected _onStatusUpdated = new Subject(); +export class YjsPartitionImpl + extends YjsSharedDocument + implements YjsPartition +{ protected _hasRegisteredSubs = false; - private _sub = new Subscription(); - private _localId: number; - private _remoteId: number; - private _doc: Doc = new Doc(); private _bots: Map; private _masks: Map; private _internalPartition: MemoryPartitionImpl; - private _currentVersion: CurrentVersion; - private _indexeddb: YjsIndexedDBPersistence; - private _persistence: YjsPartitionConfig['localPersistence']; - private _isRemoteUpdate: boolean = false; - private _isLocalTransaction: boolean = true; private _remoteEvents: PartitionRemoteEvents | boolean; private _connectionId: string; @@ -135,29 +124,13 @@ export class YjsPartitionImpl implements YjsPartition { return this._internalPartition.onStateUpdated; } - get onVersionUpdated(): Observable { - return this._onVersionUpdated; - } - - get onError(): Observable { - return this._onError; - } - - get onEvents(): Observable { - return this._onEvents; - } - - get onStatusUpdated(): Observable { - return this._onStatusUpdated; - } - unsubscribe() { return this._sub.unsubscribe(); } - get closed(): boolean { - return this._sub.closed; - } + // get doc() { + // return this._doc; + // } get state(): BotsState { return this._internalPartition.state; @@ -165,6 +138,7 @@ export class YjsPartitionImpl implements YjsPartition { type = 'yjs' as const; private: boolean; + get space(): string { return this._internalPartition.space; } @@ -177,38 +151,16 @@ export class YjsPartitionImpl implements YjsPartition { return 'immediate'; } - get doc() { - return this._doc; - } - - private get _remoteSite() { - return this._remoteId.toString(); - } - - private get _currentSite() { - return this._localId.toString(); - } - constructor(config: YjsPartitionConfig) { + super(config); this.private = config.private || false; - this._persistence = config.localPersistence; this._remoteEvents = config.remoteEvents; this._connectionId = config.connectionId; - this._localId = this._doc.clientID; - this._remoteId = new Doc().clientID; this._bots = this._doc.getMap('bots'); this._masks = this._doc.getMap('masks'); this._doc.on('afterTransaction', (transaction: Transaction) => { this._processTransaction(transaction); }); - this._currentVersion = { - currentSite: this._localId.toString(), - remoteSite: this._remoteId.toString(), - vector: {}, - }; - this._onVersionUpdated = new BehaviorSubject( - this._currentVersion - ); this._internalPartition = new MemoryPartitionImpl({ type: 'memory', initialState: {}, @@ -388,49 +340,6 @@ export class YjsPartitionImpl implements YjsPartition { return []; } - async init(): Promise {} - - connect(): void { - if (this._persistence?.saveToIndexedDb) { - console.log('[YjsPartition] Using IndexedDB persistence'); - this._indexeddb = new YjsIndexedDBPersistence( - this._persistence.database, - this._doc, - { broadcastChanges: true } - ); - } - - this._onStatusUpdated.next({ - type: 'connection', - connected: true, - }); - - this._onStatusUpdated.next({ - type: 'authentication', - authenticated: true, - }); - - this._onStatusUpdated.next({ - type: 'authorization', - authorized: true, - }); - - if (this._indexeddb) { - // wait to send the initial sync event until the persistence is ready - this._indexeddb.waitForInit().then(() => { - this._onStatusUpdated.next({ - type: 'sync', - synced: true, - }); - }); - } else { - this._onStatusUpdated.next({ - type: 'sync', - synced: true, - }); - } - } - private _applyEvents( events: (AddBotAction | RemoveBotAction | UpdateBotAction)[] ) { @@ -523,18 +432,6 @@ export class YjsPartitionImpl implements YjsPartition { }); } - private _applyUpdates(updates: string[], transactionOrigin?: string) { - try { - this._isRemoteUpdate = true; - for (let updateBase64 of updates) { - const update = toByteArray(updateBase64); - applyUpdate(this._doc, update, transactionOrigin); - } - } finally { - this._isRemoteUpdate = false; - } - } - private async _processTransaction(transaction: Transaction) { let memoryEvents: (AddBotAction | RemoveBotAction | UpdateBotAction)[] = [];