import { MetaContext, MetaObject } from '../../MetaContext'; import { $CONSTRUCT, Construct, $Construct } from './$construct'; export const $CLONE = '$clone'; export type Clone = (obj: T) => T; export type $Clone = { [$CLONE]: Clone }; export const withClone = MetaContext>(MetaContextBase: TMetaContextBase) => class extends MetaContextBase { [$CLONE](value: T) { return this.resolveValue(value)[$CLONE](value, this) as T; } }; export type GenericClone = (obj: T, clonefn: Clone, constructfn: Construct, context: any) => T; export function deepClone(genericClone: GenericClone) { return function $clone(this: MetaObject & $Construct, obj: T, context: MetaContext & $Clone) { const clonefn = context[$CLONE]; return (this[$CLONE] = function $clone(this: MetaObject & $Construct, obj: T, context: MetaContext) { return genericClone(obj, clonefn, this[$CONSTRUCT].bind(this), context); }).call(this, obj, context) as T; }; } export function primitiveClone(value: T) { return value; } export function primitiveWrapperClone(this: MetaObject, obj: T): T { return this[$CONSTRUCT](obj.valueOf()); }