import { readQuery , setQuery } from './utils' ; export interface BespokeStateOption { history ? : boolean ; } const coerceInt = ( ns ) => { const coerced = Number . parseInt ( ns , 10 ) ; return Number . isNaN ( coerced ) ? null : coerced ; } ; const bespokeState = ( opts = { } ) => { const options = { history : true , ... opts } ; return ( deck ) => { let internalNavigation = true ; const navInternally = ( action ) => { const previous = internalNavigation ; try { internalNavigation = true ; return action ( ) ; } finally { internalNavigation = previous ; } } ; const activateSlide = ( index , fragment ) => { const { min , max } = Math ; const { fragments , slides } = deck ; const idx = max ( 0 , min ( index , slides . length - 1 ) ) ; const frag = max ( 0 , min ( fragment || 0 , fragments [ idx ] . length - 1 ) ) ; if ( idx !== deck . slide ( ) || frag !== deck . fragmentIndex ) deck . slide ( idx , { fragment : frag } ) ; } ; const parseState = ( opts = { fragment : true } ) => { const page = ( coerceInt ( location . hash . slice ( 1 ) ) || 1 ) - 1 ; const fragment = opts . fragment ? coerceInt ( readQuery ( 'f' ) || '' ) : null ; activateSlide ( page , fragment ) ; } ; deck . on ( 'fragment' , ( { index , fragmentIndex } ) => { if ( internalNavigation ) return ; setQuery ( { f : fragmentIndex === 0 || fragmentIndex . toString ( ) } , { location : { ... location , hash : `#${ index + 1 }` } , setter : ( ... args ) => options . history ? history . pushState ( ... args ) : history . replaceState ( ... args ) , } ) ; } ) ; setTimeout ( ( ) => { parseState ( ) ; window . addEventListener ( 'hashchange' , ( ) => navInternally ( ( ) => { parseState ( { fragment : false } ) ; setQuery ( { f : undefined } ) ; } ) ) ; window . addEventListener ( 'popstate' , ( ) => { if ( ! internalNavigation ) navInternally ( ( ) => parseState ( ) ) ; } ) ; internalNavigation = false ; } , 0 ) ; } ; } ; export default bespokeState ;