import { IType , IAnyType , BaseType , isStateTreeNode , IValidationContext , IValidationResult , AnyObjectNode , TypeFlags , ExtractNodeType , assertIsType , isType , getSnapshot , devMode , ComplexType , typeCheckFailure } from "../../internal" ; hidden declare const $mstNotCustomized ; hidden const $preProcessorFailed = Symbol ( "$preProcessorFailed" ) ; hidden export interface _NotCustomized { readonly [ $mstNotCustomized ] : undefined ; } hidden export type _CustomOrOther < Custom , Other > = Custom extends _NotCustomized ? Other : Custom ; class SnapshotProcessor < IT extends IAnyType , CustomC , CustomS > extends BaseType < _CustomOrOther < CustomC , IT [ "CreationType" ] > , _CustomOrOther < CustomS , IT [ "SnapshotType" ] > , IT [ "TypeWithoutSTN" ] , ExtractNodeType < IT > > { get flags ( ) { return this . _subtype . flags | TypeFlags . SnapshotProcessor ; } constructor ( private readonly _subtype , private readonly _processors , name ? ) { super ( name || _subtype . name ) ; } describe ( ) { return `snapshotProcessor(${ this . _subtype . describe ( ) })` ; } private preProcessSnapshot ( sn ) { if ( this . _processors . preProcessor ) { return this . _processors . preProcessor . call ( null , sn ) ; } return sn as any ; } private preProcessSnapshotSafe ( sn ) { try { return this . preProcessSnapshot ( sn ) ; } catch ( e ) { return $preProcessorFailed ; } } private postProcessSnapshot ( sn ) { if ( this . _processors . postProcessor ) { return this . _processors . postProcessor . call ( null , sn ) as any ; } return sn ; } private _fixNode ( node ) { proxyNodeTypeMethods ( node . type , this , "create" ) ; const oldGetSnapshot = node . getSnapshot ; node . getSnapshot = ( ) => { return this . postProcessSnapshot ( oldGetSnapshot . call ( node ) ) as any ; } ; node . getReconciliationType = ( ) => { return this ; } ; } instantiate ( parent , subpath , environment , initialValue ) { const processedInitialValue = isStateTreeNode ( initialValue ) ? initialValue : this . preProcessSnapshot ( initialValue ) ; const node = this . _subtype . instantiate ( parent , subpath , environment , processedInitialValue ) as any ; this . _fixNode ( node ) ; return node ; } reconcile ( current , newValue , parent , subpath ) { const node = this . _subtype . reconcile ( current , isStateTreeNode ( newValue ) ? newValue : this . preProcessSnapshot ( newValue ) , parent , subpath ) as any ; if ( node !== current ) { this . _fixNode ( node ) ; } return node ; } getSnapshot ( node , applyPostProcess = true ) { const sn = this . _subtype . getSnapshot ( node ) ; return applyPostProcess ? this . postProcessSnapshot ( sn ) : sn ; } isValidSnapshot ( value , context ) { const processedSn = this . preProcessSnapshotSafe ( value ) ; if ( processedSn === $preProcessorFailed ) { return typeCheckFailure ( context , value , "Failed to preprocess value" ) ; } return this . _subtype . validate ( processedSn , context ) ; } getSubTypes ( ) { return this . _subtype ; } is ( thing ) { const value = isType ( thing ) ? this . _subtype : isStateTreeNode ( thing ) ? getSnapshot ( thing , false ) : this . preProcessSnapshotSafe ( thing ) ; if ( value === $preProcessorFailed ) { return false ; } return this . _subtype . validate ( value , [ { path : "" , type : this . _subtype } ] ) . length === 0 ; } isAssignableFrom ( type ) { return this . _subtype . isAssignableFrom ( type ) ; } isMatchingSnapshotId ( current , snapshot ) { if ( ! ( this . _subtype instanceof ComplexType ) ) { return false ; } const processedSn = this . preProcessSnapshot ( snapshot ) ; return this . _subtype . isMatchingSnapshotId ( current as any , processedSn ) ; } } function proxyNodeTypeMethods ( nodeType , snapshotProcessorType , ... methods ) { for ( const method of methods ) { nodeType [ method ] = snapshotProcessorType [ method ] . bind ( snapshotProcessorType ) ; } } /**
 * A type that has its snapshots processed.
 */ export interface ISnapshotProcessor < IT extends IAnyType , CustomC , CustomS > extends IType < _CustomOrOther < CustomC , IT [ "CreationType" ] > , _CustomOrOther < CustomS , IT [ "SnapshotType" ] > , IT [ "TypeWithoutSTN" ] > { } /**
 * Snapshot processors.
 */ export interface ISnapshotProcessors < C , CustomC , S , CustomS > { /**
     * Function that transforms an input snapshot.
     */ preProcessor ? ( snapshot ) : C ; param snapshot postProcessor ? ( snapshot ) : CustomS ; } param type param processors param name returns export function snapshotProcessor < IT extends IAnyType , CustomC = _NotCustomized , CustomS = _NotCustomized > ( type , processors , name ? ) { assertIsType ( type , 1 ) ; if ( devMode ( ) ) { if ( processors . postProcessor && typeof processors . postProcessor !== "function" ) { throw fail ( "postSnapshotProcessor must be a function" ) ; } if ( processors . preProcessor && typeof processors . preProcessor !== "function" ) { throw fail ( "preSnapshotProcessor must be a function" ) ; } } return new SnapshotProcessor ( type , processors , name ) ; }