import { createDecoratorOrDecoratorFactory , MemberDescriptor , ClassDescriptor , isMethod , MethodMemberDescriptor , isClass , createMemberDescriptor , defaultFieldAttributes , isNonStatic , defaultMethodAttributes , createDecorator } from "@esfx/decorators-stage1-core" ; let mapStore ; function getBoundSuper ( obj , fn ) { if ( ! mapStore ) mapStore = new WeakMap ( ) ; let superStore = mapStore . get ( obj ) ; if ( ! superStore ) mapStore . set ( obj , superStore = new WeakMap ( ) ) ; let boundFn = superStore . get ( fn ) ; if ( ! boundFn ) superStore . set ( fn , boundFn = fn . bind ( obj ) ) ; return boundFn ; } function autobindClass ( klass ) { const descriptors = Object . getOwnPropertyDescriptors ( klass . target . prototype ) ; for ( const key of Object . getOwnPropertyNames ( descriptors ) ) { if ( key === "constructor" ) continue ; const member = createMemberDescriptor ( klass . target . prototype , key , descriptors [ key ] ) ; if ( isMethod ( member ) ) Object . defineProperty ( klass . target . prototype , key , autobindMethod ( member ) ) ; } for ( const key of Object . getOwnPropertySymbols ( descriptors ) ) { const member = createMemberDescriptor ( klass . target . prototype , key , descriptors [ key as any ] ) ; if ( isMethod ( member ) ) Object . defineProperty ( klass . target . prototype , key , autobindMethod ( member ) ) ; } } function autobindMethod ( { target , target : { constructor } , key , descriptor : { value : fn , enumerable , configurable , writable } } ) { return { enumerable , configurable , get ( this ) { if ( this === target ) return fn ; if ( this . constructor !== constructor && Object . getPrototypeOf ( this ) . constructor === constructor ) return fn ; if ( this . constructor !== constructor && key in this . constructor . prototype ) return getBoundSuper ( this , fn ) ; const boundFn = fn . bind ( this ) ; Object . defineProperty ( this , key , { ... defaultMethodAttributes , value : boundFn } ) ; return boundFn ; } , set : writable ? function ( this , value ) { Object . defineProperty ( this , key , { ... defaultFieldAttributes , value } ) ; } : undefined } ; } function autobindDecorator ( descriptor ) ; function autobindDecorator ( descriptor ) ; function autobindDecorator ( descriptor ) { if ( isClass ( descriptor ) ) return autobindClass ( descriptor ) ; if ( isMethod ( descriptor ) && isNonStatic ( descriptor ) ) return autobindMethod ( descriptor ) ; throw new TypeError ( `'@autobind' is only supported on classes and non-static methods.` ) ; } export const autobind = createDecorator ( autobindDecorator ) ;