From a3ce67a59dfca8d16eea596d6e48cee639a6fba5 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Fri, 14 Mar 2025 12:31:39 +0000 Subject: [PATCH] refactor(editor): separate init logic of flat model (#10862) --- .../store/src/reactive/flat-native-y/index.ts | 63 +++---------------- .../src/reactive/flat-native-y/initialize.ts | 59 +++++++++++++++++ 2 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 blocksuite/framework/store/src/reactive/flat-native-y/initialize.ts diff --git a/blocksuite/framework/store/src/reactive/flat-native-y/index.ts b/blocksuite/framework/store/src/reactive/flat-native-y/index.ts index d6c516d1a..8acd33c86 100644 --- a/blocksuite/framework/store/src/reactive/flat-native-y/index.ts +++ b/blocksuite/framework/store/src/reactive/flat-native-y/index.ts @@ -1,12 +1,6 @@ -import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { signal } from '@preact/signals-core'; import type { Subject } from 'rxjs'; -import { - Array as YArray, - Map as YMap, - Text as YText, - type YMapEvent, -} from 'yjs'; +import { Array as YArray, type Map as YMap, type YMapEvent } from 'yjs'; import { BaseReactiveYData } from '../base-reactive-data'; import { Boxed, type OnBoxedChange } from '../boxed'; @@ -14,6 +8,7 @@ import { y2Native } from '../native-y'; import { ReactiveYArray } from '../proxy'; import { type OnTextChange, Text } from '../text'; import type { ProxyOptions, UnRecord } from '../types'; +import { initializeData } from './initialize'; import { createProxy } from './proxy'; import type { OnChange } from './types'; import { @@ -137,57 +132,14 @@ export class ReactiveFlatYMap extends BaseReactiveYData< }; }; - private readonly _createDefaultData = (): UnRecord => { - const root: UnRecord = {}; - const transform = this._transform; - Array.from(this._ySource.entries()).forEach(([key, value]) => { - if (key.startsWith('sys')) { - return; - } - const keys = keyWithoutPrefix(key).split('.'); - const firstKey = keys[0]; - - let finalData = value; - if (Boxed.is(value)) { - finalData = transform(firstKey, new Boxed(value), value); - } else if (value instanceof YArray) { - finalData = transform(firstKey, value.toArray(), value); - } else if (value instanceof YText) { - const next = new Text(value); - finalData = transform(firstKey, next, value); - } else if (value instanceof YMap) { - throw new BlockSuiteError( - ErrorCode.ReactiveProxyError, - 'flatY2Native does not support Y.Map as value of Y.Map' - ); - } else { - finalData = transform(firstKey, value, value); - } - const allLength = keys.length; - void keys.reduce((acc: UnRecord, key, index) => { - if (!acc[key] && index !== allLength - 1) { - const path = keys.slice(0, index + 1).join('.'); - const data = this._getProxy({} as UnRecord, root, path); - acc[key] = data; - } - if (index === allLength - 1) { - acc[key] = finalData; - } - return acc[key] as UnRecord; - }, root); - }); - - return root; - }; - private _byPassYjs = false; private readonly _getProxy = ( source: UnRecord, root: UnRecord, path?: string - ): UnRecord => { - return createProxy({ + ): UnRecord => + createProxy({ yMap: this._ySource, base: source, root, @@ -201,7 +153,6 @@ export class ReactiveFlatYMap extends BaseReactiveYData< stashed: this._stashed, initialized: () => this._initialized, }); - }; private readonly _updateWithYjsSkip = (fn: () => void) => { this._byPassYjs = true; @@ -216,7 +167,11 @@ export class ReactiveFlatYMap extends BaseReactiveYData< ) { super(); this._initialized = false; - const source = this._createDefaultData(); + const source = initializeData({ + getProxy: this._getProxy, + transform: this._transform, + yMap: this._ySource, + }); this._source = source; const proxy = this._getProxy(source, source); diff --git a/blocksuite/framework/store/src/reactive/flat-native-y/initialize.ts b/blocksuite/framework/store/src/reactive/flat-native-y/initialize.ts new file mode 100644 index 000000000..8ce6a16ff --- /dev/null +++ b/blocksuite/framework/store/src/reactive/flat-native-y/initialize.ts @@ -0,0 +1,59 @@ +import { BlockSuiteError } from '@blocksuite/global/exceptions'; +import { Array as YArray, Map as YMap, Text as YText } from 'yjs'; + +import { Boxed } from '../boxed'; +import { Text } from '../text'; +import type { UnRecord } from '../types'; +import type { CreateProxyOptions } from './types'; +import { keyWithoutPrefix } from './utils'; + +type InitializeDataOptions = Pick & { + getProxy: (source: UnRecord, root: UnRecord, path?: string) => UnRecord; +}; + +// Create default data object from yjs map +export const initializeData = ({ + getProxy, + transform, + yMap, +}: InitializeDataOptions): UnRecord => { + const root: UnRecord = {}; + Array.from(yMap.entries()).forEach(([key, value]) => { + if (key.startsWith('sys')) { + return; + } + const keys = keyWithoutPrefix(key).split('.'); + const firstKey = keys[0]; + + let finalData = value; + if (Boxed.is(value)) { + finalData = transform(firstKey, new Boxed(value), value); + } else if (value instanceof YArray) { + finalData = transform(firstKey, value.toArray(), value); + } else if (value instanceof YText) { + const next = new Text(value); + finalData = transform(firstKey, next, value); + } else if (value instanceof YMap) { + throw new BlockSuiteError( + BlockSuiteError.ErrorCode.ReactiveProxyError, + 'flatY2Native does not support Y.Map as value of Y.Map' + ); + } else { + finalData = transform(firstKey, value, value); + } + const allLength = keys.length; + void keys.reduce((acc: UnRecord, key, index) => { + if (!acc[key] && index !== allLength - 1) { + const path = keys.slice(0, index + 1).join('.'); + const data = getProxy({} as UnRecord, root, path); + acc[key] = data; + } + if (index === allLength - 1) { + acc[key] = finalData; + } + return acc[key] as UnRecord; + }, root); + }); + + return root; +};