import { IKeyboardInput } from "./interfaces" ; export type KeyboardEventWriteStream = ( e : IKeyboardInput ) => boolean | void ; const createInputWriteStream = ( input ) => ( stream ) => stream ( input ) === false ; export default class KeyboardEventReadStream { private _isOpen : boolean ; private _tabIndexAttached : boolean ; private readonly _writers : KeyboardEventWriteStream [ ] ; public static createByEvent ( event , target ? ) { return new KeyboardEventReadStream ( event , target ) ; } private constructor ( private _event , private _target = document ) { this . _isOpen = true ; this . _writers = [ ] ; if ( _target instanceof Element && ! _target . hasAttribute ( "tabindex" ) ) { _target . setAttribute ( "tabindex" , "0" ) ; this . _tabIndexAttached = true ; } this . _target . addEventListener ( this . _event , this . _onEvent , { passive : true } ) ; } public get inOpen ( ) : boolean { return this . _isOpen ; } public close ( ) { this . _isOpen = false ; this . _writers . length = 0 ; this . _target . removeEventListener ( this . _event , this . _onEvent ) ; if ( this . _tabIndexAttached ) { ( this . _target as Element ) . removeAttribute ( "tabindex" ) ; this . _tabIndexAttached = false ; } } public pipe ( targetStream ) { if ( this . _writers . indexOf ( targetStream ) > - 1 ) { return this ; } this . _writers . push ( targetStream ) ; return this ; } public unpipe ( targetStream ) { const targetStreamLocation = this . _writers . indexOf ( targetStream ) ; if ( targetStreamLocation > - 1 ) { this . _writers . splice ( targetStreamLocation , 1 ) ; } return this ; } private _onEvent = ( e ) => { if ( ! this . _writers . length || e . key . toLowerCase ( ) === "dead" ) { return ; } const write = createInputWriteStream ( { key : e . key . toLowerCase ( ) , code : e . which } ) ; this . _writers . find ( write ) ; } ; }