mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
Remove circular dep (#790)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
a7fcf166fa
commit
2bbf921fde
@ -16,12 +16,10 @@
|
|||||||
import type { AnyAttribute, Class, Classifier, Doc, Domain, Interface, Mixin, Obj, Ref } from './classes'
|
import type { AnyAttribute, Class, Classifier, Doc, Domain, Interface, Mixin, Obj, Ref } from './classes'
|
||||||
import { ClassifierKind } from './classes'
|
import { ClassifierKind } from './classes'
|
||||||
import core from './component'
|
import core from './component'
|
||||||
|
import { _createMixinProxy, _mixinClass, _toDoc } from './proxy'
|
||||||
import type { Tx, TxCreateDoc, TxMixin } from './tx'
|
import type { Tx, TxCreateDoc, TxMixin } from './tx'
|
||||||
import { TxProcessor } from './tx'
|
import { TxProcessor } from './tx'
|
||||||
|
|
||||||
const PROXY_TARGET_KEY = '$___proxy_target'
|
|
||||||
const PROXY_MIXIN_CLASS_KEY = '$__mixin'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -36,22 +34,7 @@ export class Hierarchy {
|
|||||||
const value = this.getClass(mixin)
|
const value = this.getClass(mixin)
|
||||||
const ancestor = this.getClass(value.extends as Ref<Class<Obj>>)
|
const ancestor = this.getClass(value.extends as Ref<Class<Obj>>)
|
||||||
const ancestorProxy = ancestor.kind === ClassifierKind.MIXIN ? this.getMixinProxyHandler(ancestor._id) : null
|
const ancestorProxy = ancestor.kind === ClassifierKind.MIXIN ? this.getMixinProxyHandler(ancestor._id) : null
|
||||||
return {
|
return _createMixinProxy(value, ancestorProxy)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMixinProxyHandler (mixin: Ref<Mixin<Doc>>): ProxyHandler<Doc> {
|
private getMixinProxyHandler (mixin: Ref<Mixin<Doc>>): ProxyHandler<Doc> {
|
||||||
@ -69,15 +52,11 @@ export class Hierarchy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static toDoc<D extends Doc>(doc: D): D {
|
static toDoc<D extends Doc>(doc: D): D {
|
||||||
const targetDoc = (doc as any)[PROXY_TARGET_KEY]
|
return _toDoc(doc)
|
||||||
if (targetDoc !== undefined) {
|
|
||||||
return targetDoc as D
|
|
||||||
}
|
|
||||||
return doc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static mixinClass<D extends Doc, M extends D>(doc: D): Ref<Mixin<M>>|undefined {
|
static mixinClass<D extends Doc, M extends D>(doc: D): Ref<Mixin<M>>|undefined {
|
||||||
return (doc as any)[PROXY_MIXIN_CLASS_KEY]
|
return _mixinClass(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMixin<D extends Doc, M extends D>(doc: D, mixin: Ref<Mixin<M>>): boolean {
|
hasMixin<D extends Doc, M extends D>(doc: D, mixin: Ref<Mixin<M>>): boolean {
|
||||||
|
45
packages/core/src/proxy.ts
Normal file
45
packages/core/src/proxy.ts
Normal file
@ -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<Doc>, ancestorProxy: ProxyHandler<Doc> | null): ProxyHandler<Doc> {
|
||||||
|
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<D extends Doc> (doc: D): D {
|
||||||
|
const targetDoc = (doc as any)[PROXY_TARGET_KEY]
|
||||||
|
if (targetDoc !== undefined) {
|
||||||
|
return targetDoc as D
|
||||||
|
}
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export function _mixinClass<D extends Doc, M extends D> (doc: D): Ref<Mixin<M>>|undefined {
|
||||||
|
return (doc as any)[PROXY_MIXIN_CLASS_KEY]
|
||||||
|
}
|
@ -14,12 +14,12 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type { KeysByType } from 'simplytyped'
|
import type { KeysByType } from 'simplytyped'
|
||||||
import type { Class, Data, Doc, Domain, Ref, Account, Space, Arr, Mixin, PropertyType, AttachedDoc, AttachedData } from './classes'
|
import type { Account, Arr, AttachedData, AttachedDoc, Class, Data, Doc, Domain, Mixin, PropertyType, Ref, Space } from './classes'
|
||||||
import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, TxResult } from './storage'
|
|
||||||
import core from './component'
|
import core from './component'
|
||||||
import { generateId } from './utils'
|
|
||||||
import { _getOperator } from './operator'
|
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
|
* @public
|
||||||
@ -239,7 +239,7 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static updateDoc2Doc<T extends Doc>(rawDoc: T, tx: TxUpdateDoc<T>): T {
|
static updateDoc2Doc<T extends Doc>(rawDoc: T, tx: TxUpdateDoc<T>): T {
|
||||||
const doc = Hierarchy.toDoc(rawDoc)
|
const doc = _toDoc(rawDoc)
|
||||||
const ops = tx.operations as any
|
const ops = tx.operations as any
|
||||||
for (const key in ops) {
|
for (const key in ops) {
|
||||||
if (key.startsWith('$')) {
|
if (key.startsWith('$')) {
|
||||||
@ -256,7 +256,7 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
|
|
||||||
static updateMixin4Doc<D extends Doc, M extends D>(rawDoc: D, mixinClass: Ref<Class<M>>, operations: MixinUpdate<D, M>): D {
|
static updateMixin4Doc<D extends Doc, M extends D>(rawDoc: D, mixinClass: Ref<Class<M>>, operations: MixinUpdate<D, M>): D {
|
||||||
const ops = operations as any
|
const ops = operations as any
|
||||||
const doc = Hierarchy.toDoc(rawDoc)
|
const doc = _toDoc(rawDoc)
|
||||||
const mixin = (doc as any)[mixinClass] ?? {}
|
const mixin = (doc as any)[mixinClass] ?? {}
|
||||||
for (const key in ops) {
|
for (const key in ops) {
|
||||||
if (key.startsWith('$')) {
|
if (key.startsWith('$')) {
|
||||||
|
Loading…
Reference in New Issue
Block a user