import { PropertyOptions , Serializable , Target } from './api' ; import { serialize } from './serialization' ; typeparam export abstract class Prefab < T extends object > implements Serializable < T > { /**
     * The component that is hosting us.
     */ host ? : Prefab < any > ; /**
     * The list of targets this prefab should target.
     */ protected targets ? : Target [ ] ; /**
     * Every concrete extension must implement exhaustive defaults conforming to the data interface.
     */ readonly abstract defaults : Readonly < T > ; /**
     * If necessary, options may be defined.
     */ readonly options : Partial < { [ K in keyof T ] : Partial < PropertyOptions > ; } > = { } ; constructor ( private readonly overrides = { } ) { const proxy = new Proxy ( this , this ) ; this . overrides = { } ; for ( const key of Object . keys ( overrides ) as ( keyof T ) [ ] ) { if ( overrides [ key ] !== undefined ) { if ( typeof overrides [ key ] === 'object' ) { ( overrides [ key ] as any ) . host = proxy ; } this . overrides [ key ] = overrides [ key ] ; } } return proxy ; } /**
     * Proxy method, by which we subtly implement the data interface in the class itself.
     */ get ( instance , key , receiver ) { if ( instance [ key ] instanceof Function ) { return instance [ key ] . bind ( receiver ) ; } if ( instance [ key ] !== undefined ) { return instance [ key ] ; } if ( instance . overrides . hasOwnProperty ( key ) ) { return instance . overrides [ key ] ; } return instance . defaults [ key ] ; } /**
     * A local data sanitizer, which can be used for pinning scalar values and any other data normalization needs.
     */ protected sanitize ( data ) { return data ; } /**
     * Serializable<T> interface.
     *
     * Generic serialization instructions. These can be overridden as needed.
     */ serialize ( ) { return serialize ( this . sanitize ( Object . assign ( this . defaults , this . overrides ) ) ) ; } toPresentableValue ( ) { return '' ; } } /**
 * A typing which acknowledges the Proxy by which Prefab<T> actually implements T.
 */ type PrefabConstructor < T extends object > = new ( overrides ? ) => Prefab < T > & T ; typeparam export const prefab = < T extends object > ( ) : PrefabConstructor < T > => Prefab . prototype . constructor as PrefabConstructor < T > ;