diff --git a/packages/core/src/hierarchy.ts b/packages/core/src/hierarchy.ts index 2dd2e6f416..0c47c03301 100644 --- a/packages/core/src/hierarchy.ts +++ b/packages/core/src/hierarchy.ts @@ -16,12 +16,10 @@ import type { AnyAttribute, Class, Classifier, Doc, Domain, Interface, Mixin, Obj, Ref } from './classes' import { ClassifierKind } from './classes' import core from './component' +import { _createMixinProxy, _mixinClass, _toDoc } from './proxy' import type { Tx, TxCreateDoc, TxMixin } from './tx' import { TxProcessor } from './tx' -const PROXY_TARGET_KEY = '$___proxy_target' -const PROXY_MIXIN_CLASS_KEY = '$__mixin' - /** * @public */ @@ -36,22 +34,7 @@ export class Hierarchy { const value = this.getClass(mixin) const ancestor = this.getClass(value.extends as Ref>) const ancestorProxy = ancestor.kind === ClassifierKind.MIXIN ? this.getMixinProxyHandler(ancestor._id) : null - return { - get (target: any, property: string, receiver: any): any { - if (property === PROXY_TARGET_KEY) { - return target - } - // We need to override _class property, to return proper mixin class. - if (property === PROXY_MIXIN_CLASS_KEY) { - return mixin - } - const value = target[mixin]?.[property] - if (value === undefined) { - return ancestorProxy !== null ? ancestorProxy.get?.(target, property, receiver) : target[property] - } - return value - } - } + return _createMixinProxy(value, ancestorProxy) } private getMixinProxyHandler (mixin: Ref>): ProxyHandler { @@ -69,15 +52,11 @@ export class Hierarchy { } static toDoc(doc: D): D { - const targetDoc = (doc as any)[PROXY_TARGET_KEY] - if (targetDoc !== undefined) { - return targetDoc as D - } - return doc + return _toDoc(doc) } static mixinClass(doc: D): Ref>|undefined { - return (doc as any)[PROXY_MIXIN_CLASS_KEY] + return _mixinClass(doc) } hasMixin(doc: D, mixin: Ref>): boolean { diff --git a/packages/core/src/proxy.ts b/packages/core/src/proxy.ts new file mode 100644 index 0000000000..d32b1ffae5 --- /dev/null +++ b/packages/core/src/proxy.ts @@ -0,0 +1,45 @@ +import { Ref } from '.' +import type { Doc, Mixin } from './classes' + +const PROXY_TARGET_KEY = '$___proxy_target' +const PROXY_MIXIN_CLASS_KEY = '$__mixin' + +/** + * @internal + */ +export function _createMixinProxy (mixin: Mixin, ancestorProxy: ProxyHandler | null): ProxyHandler { + return { + get (target: any, property: string, receiver: any): any { + if (property === PROXY_TARGET_KEY) { + return target + } + // We need to override _class property, to return proper mixin class. + if (property === PROXY_MIXIN_CLASS_KEY) { + return mixin._id + } + const value = target[mixin._id]?.[property] + if (value === undefined) { + return ancestorProxy !== null ? ancestorProxy.get?.(target, property, receiver) : target[property] + } + return value + } + } +} + +/** + * @internal + */ +export function _toDoc (doc: D): D { + const targetDoc = (doc as any)[PROXY_TARGET_KEY] + if (targetDoc !== undefined) { + return targetDoc as D + } + return doc +} + +/** + * @internal + */ +export function _mixinClass (doc: D): Ref>|undefined { + return (doc as any)[PROXY_MIXIN_CLASS_KEY] +} diff --git a/packages/core/src/tx.ts b/packages/core/src/tx.ts index 044d266f89..5546e51897 100644 --- a/packages/core/src/tx.ts +++ b/packages/core/src/tx.ts @@ -14,12 +14,12 @@ // import type { KeysByType } from 'simplytyped' -import type { Class, Data, Doc, Domain, Ref, Account, Space, Arr, Mixin, PropertyType, AttachedDoc, AttachedData } from './classes' -import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, TxResult } from './storage' +import type { Account, Arr, AttachedData, AttachedDoc, Class, Data, Doc, Domain, Mixin, PropertyType, Ref, Space } from './classes' import core from './component' -import { generateId } from './utils' import { _getOperator } from './operator' -import { Hierarchy } from './hierarchy' +import { _toDoc } from './proxy' +import type { DocumentQuery, FindOptions, FindResult, Storage, TxResult, WithLookup } from './storage' +import { generateId } from './utils' /** * @public @@ -239,7 +239,7 @@ export abstract class TxProcessor implements WithTx { } static updateDoc2Doc(rawDoc: T, tx: TxUpdateDoc): T { - const doc = Hierarchy.toDoc(rawDoc) + const doc = _toDoc(rawDoc) const ops = tx.operations as any for (const key in ops) { if (key.startsWith('$')) { @@ -256,7 +256,7 @@ export abstract class TxProcessor implements WithTx { static updateMixin4Doc(rawDoc: D, mixinClass: Ref>, operations: MixinUpdate): D { const ops = operations as any - const doc = Hierarchy.toDoc(rawDoc) + const doc = _toDoc(rawDoc) const mixin = (doc as any)[mixinClass] ?? {} for (const key in ops) { if (key.startsWith('$')) {