import { Dialogic } from "./index" ; import { actions , createId , selectors } from "./state/store" ; import { Timer , TimerStore } from "./state/timer" ; import { MODE , transition } from "./transition" ; import { pipe } from "./utils" ; export { actions , selectors , states } from "./state/store" ; const localState = { uid : 0 , } ; const getUid = ( ) => { if ( localState . uid === Number . MAX_VALUE ) { localState . uid = 0 ; } else { localState . uid += 1 ; } return localState . uid ; } ; enum TransitionStates { Default , Displaying , Hiding } const getMaybeItem = < T = unknown > ( ns ) => ( defaultDialogicOptions ) => ( identityOptions ? ) => selectors . find < T > ( ns , getMergedIdentityOptions ( defaultDialogicOptions , identityOptions ) ) ; const filterBySpawn = < T = unknown > ( identityOptions ) => ( items ) => identityOptions . spawn !== undefined ? items . filter ( ( item ) => item . identityOptions . spawn === identityOptions . spawn ) : items ; const filterById = < T = unknown > ( identityOptions ) => ( items ) => identityOptions . id !== undefined ? items . filter ( ( item ) => item . identityOptions . id === identityOptions . id ) : items ; /**
 * Gets a list of all non-queued items.
 * From the queued items only the first item is listed.
 * */ const filterFirstInQueue = < T = unknown > ( nsItems ) => { let queuedCount = 0 ; return nsItems . map ( ( item ) => ( { item , queueCount : item . dialogicOptions . queued ? queuedCount ++ : 0 , } ) ) . filter ( ( { queueCount } ) => queueCount === 0 ) . map ( ( { item } ) => item ) ; } ; export const filterCandidates = ( ns , items , identityOptions ) : Dialogic . Item [ ] => { const nsItems = ( items [ ns ] || [ ] ) as Dialogic . Item [ ] ; if ( nsItems . length === 0 ) { return [ ] ; } return pipe ( filterBySpawn ( identityOptions ) , filterFirstInQueue ) ( nsItems ) ; } ; type TGetPassThroughOptions = < T = unknown > ( options : Dialogic . Options < T > ) => T ; const getPassThroughOptions = ( options ) => { const copy = { ... options , } ; delete copy . dialogic ; return copy ; } ; const getMergedIdentityOptions = ( defaultDialogicOptions , identityOptions = { } ) => ( { id : identityOptions . id || defaultDialogicOptions . id , spawn : identityOptions . spawn || defaultDialogicOptions . spawn , } as Dialogic . IdentityOptions ) ; const handleOptions = < T = unknown > ( defaultDialogicOptions , options = { } as T ) => { const identityOptions = { id : options . dialogic ? options . dialogic . id : undefined , spawn : options . dialogic ? options . dialogic . spawn : undefined , } ; const mergedIdentityOptions = getMergedIdentityOptions ( defaultDialogicOptions || ( { } as Dialogic . DefaultDialogicOptions ) , identityOptions ) ; const dialogicOptions = { ... defaultDialogicOptions , ... options . dialogic , __transitionTimeoutId__ : 0 , } ; const passThroughOptions = getPassThroughOptions ( options ) ; return { identityOptions : mergedIdentityOptions , dialogicOptions , passThroughOptions , } ; } ; const createInstance = ( ns ) => ( defaultDialogicOptions ) => < T = unknown > ( options ? ) => { const { identityOptions , dialogicOptions , passThroughOptions } = handleOptions ( defaultDialogicOptions , options ) ; return new Promise < Dialogic . Item < T > > ( ( resolve ) => { const callbacks = { willShow : ( item ) => { if ( dialogicOptions . willShow ) { dialogicOptions . willShow ( item ) ; } return resolve ( item ) ; } , willHide : ( item ) => { if ( dialogicOptions . willHide ) { dialogicOptions . willHide ( item ) ; } return resolve ( item ) ; } , didShow : ( item ) => { if ( dialogicOptions . didShow ) { dialogicOptions . didShow ( item ) ; } return resolve ( item ) ; } , didHide : ( item ) => { if ( dialogicOptions . didHide ) { dialogicOptions . didHide ( item ) ; } return resolve ( item ) ; } , } ; const item = { ns , identityOptions , dialogicOptions , callbacks , passThroughOptions , id : createId ( identityOptions , ns ) , timer : dialogicOptions . timeout ? TimerStore ( ) : undefined , key : getUid ( ) . toString ( ) , transitionState : TransitionStates . Default , } ; const maybeExistingItem = selectors . find < T > ( ns , identityOptions ) ; const existingItem = maybeExistingItem . just ; if ( existingItem && dialogicOptions . toggle ) { hide ( ns ) ( defaultDialogicOptions ) < T > ( options ) ; return resolve ( existingItem ) ; } if ( existingItem && ! dialogicOptions . queued ) { const replacingItem = { ... item , key : existingItem . key , transitionState : existingItem . transitionState , dialogicOptions : existingItem . dialogicOptions , } ; actions . replace ( ns , existingItem . id , replacingItem as Dialogic . Item < T > ) ; } else { actions . add < T > ( ns , item ) ; } resolve ( item ) ; } ) ; } ; export const show = createInstance ; export const hide = ( ns ) => ( defaultDialogicOptions ) => < T = unknown > ( options ? ) => { const { identityOptions , dialogicOptions , passThroughOptions } = handleOptions ( defaultDialogicOptions , options ) ; const maybeExistingItem = selectors . find < T > ( ns , identityOptions ) ; const existingItem = maybeExistingItem . just ; if ( existingItem ) { const item = { ... existingItem , dialogicOptions : { ... existingItem . dialogicOptions , ... dialogicOptions , } , passThroughOptions : { ... existingItem . passThroughOptions , passThroughOptions , } , } ; actions . replace < T > ( ns , existingItem . id , item ) ; if ( item . transitionState !== TransitionStates . Hiding ) { return hideItem < T > ( item ) ; } return Promise . resolve ( item ) ; } return Promise . resolve ( { ns , id : identityOptions . id , } as Dialogic . Item < T > ) ; } ; export const pause = ( ns ) => ( _defaultDialogicOptions ) => < T = unknown > ( identityOptions ? ) => { const validItems = getValidItems < T > ( ns , identityOptions ) . filter ( ( item ) => ! ! item . timer ) ; validItems . forEach ( ( item ) => { if ( item . timer ) { item . timer . actions . pause ( ) ; } } ) ; return Promise . all ( validItems ) ; } ; export const resume = ( ns ) => ( _defaultDialogicOptions ) => < T = unknown > ( commandOptions ? ) => { const options = commandOptions || { } ; const identityOptions = { id : options . id , spawn : options . spawn , } ; const validItems = getValidItems < T > ( ns , identityOptions ) . filter ( ( item ) => ! ! item . timer ) ; validItems . forEach ( ( item ) => { if ( item . timer ) { item . timer . actions . resume ( options . minimumDuration ) ; } } ) ; return Promise . all ( validItems ) ; } ; const getTimerSelectors = < T = unknown > ( ns , defaultDialogicOptions , identityOptions ? ) => { const maybeItem = getMaybeItem < T > ( ns ) ( defaultDialogicOptions ) ( identityOptions ) ; return maybeItem ?. just ?. timer ?. selectors ; } ; export const isPaused = ( ns ) => ( defaultDialogicOptions ) => ( identityOptions ? ) => getTimerSelectors ( ns , defaultDialogicOptions , identityOptions ) ?. isPaused ( ) || false ; export const getRemaining = ( ns ) => ( defaultDialogicOptions ) => ( identityOptions ? ) => getTimerSelectors ( ns , defaultDialogicOptions , identityOptions ) ?. getRemaining ( ) || undefined ; export const exists = ( ns ) => ( _defaultDialogicOptions ) => ( identityOptions ? ) => ! ! getValidItems ( ns , identityOptions ) . length ; const getValidItems = < T = unknown > ( ns , identityOptions ? ) => { const allItems = selectors . getAll < T > ( ns ) ; let validItems ; if ( identityOptions ) { validItems = pipe ( filterBySpawn ( identityOptions ) , filterById ( identityOptions ) ) ( allItems ) ; } else { validItems = allItems ; } return validItems ; } ; export const resetAll = ( ns ) => ( _defaultDialogicOptions ) => ( identityOptions ? ) => { const validItems = getValidItems ( ns , identityOptions ) ; const items = [ ] ; validItems . forEach ( ( item ) => { if ( item . timer ) { item . timer . actions . abort ( ) ; } items . push ( item ) ; } ) ; if ( identityOptions ) { items . forEach ( ( item ) => { actions . remove ( ns , item . id ) ; } ) ; } else { actions . removeAll ( ns ) ; } return Promise . resolve ( items ) ; } ; const getOverridingTransitionOptions = < T = unknown > ( item , dialogicOptions ) => ( { ... item , dialogicOptions : { ... item . dialogicOptions , ... dialogicOptions , } , } ) ; /**
 * Triggers a `hideItem` for each item in the store.
 * Queued items: will trigger `hideItem` only for the first item, then reset the store.
 * Optional `dialogicOptions` may be passed with specific transition options. This comes in handy when all items should hide in the same way.
 */ export const hideAll = ( ns ) => ( _defaultDialogicOptions ) => < T = unknown > ( dialogicOptions ? ) => { const options = dialogicOptions || { } ; const identityOptions = { id : options . id , spawn : options . spawn , } ; const validItems = getValidItems < T > ( ns , identityOptions ) ; const regularItems = validItems . filter ( ( item ) => ! options . queued && ! item . dialogicOptions . queued ) ; const queuedItems = validItems . filter ( ( item ) => options . queued || item . dialogicOptions . queued ) ; const items = [ ] ; regularItems . forEach ( ( item ) => items . push ( hideItem ( getOverridingTransitionOptions < T > ( item , options ) ) ) ) ; if ( queuedItems . length > 0 ) { const [ current ] = queuedItems ; actions . store ( ns , [ current ] ) ; items . push ( hideItem ( getOverridingTransitionOptions < T > ( current , options ) ) ) ; } return Promise . all ( items ) ; } ; export const getCount = ( ns ) => ( identityOptions ? ) => selectors . getCount ( ns , identityOptions ) ; const transitionItem = < T = unknown > ( item , mode ) => transition ( item . dialogicOptions , mode ) ; const getResultPromise = < T = unknown > ( ) => ( ns ) => ( defaultDialogicOptions ) => ( identityOptions ? ) => { const maybeItem = getMaybeItem < T > ( ns ) ( defaultDialogicOptions ) ( identityOptions ) ; if ( maybeItem . just ) { if ( maybeItem . just && maybeItem . just . timer ) { return maybeItem . just . timer . selectors . getResultPromise ( ) ; } return undefined ; } return undefined ; } ; const deferredHideItem = async < T = unknown > ( item , timer , timeout ) => { timer . actions . start ( ( ) => hideItem ( item ) , timeout ) ; return getResultPromise < T > ( ) ; } ; export const showItem = async < T = unknown > ( item ) => { if ( item . callbacks . willShow ) { item . callbacks . willShow ( item ) ; } if ( item . transitionState !== TransitionStates . Displaying ) { item . transitionState = TransitionStates . Displaying ; await transitionItem ( item , MODE . SHOW ) ; } if ( item . callbacks . didShow ) { item . callbacks . didShow ( item ) ; } if ( item . dialogicOptions . timeout && item . timer ) { await deferredHideItem ( item , item . timer , item . dialogicOptions . timeout ) ; } return Promise . resolve ( item ) ; } ; returns export const hideItem = async < T = unknown > ( item ) : Promise < Dialogic . Item < T > > => { item . transitionState = TransitionStates . Hiding ; if ( item . timer ) { item . timer . actions . stop ( ) ; } if ( item . callbacks . willHide ) { item . callbacks . willHide ( item ) ; } await transitionItem ( item , MODE . HIDE ) ; if ( item . callbacks . didHide ) { item . callbacks . didHide ( item ) ; } const copy = { ... item , } ; actions . remove ( item . ns , item . id ) ; return Promise . resolve ( copy ) ; } ; export const setDomElement = < T = unknown > ( domElement , item ) => { item . dialogicOptions . domElement = domElement ; } ;