import Stream from "mithril-stream-standalone" ; import { Dialogic } from "../index" ; type PatchFn = ( state : Dialogic . State ) => Dialogic . State ; const findItem = < T = unknown > ( id , items ) => items . find ( ( item ) => item . id === id ) ; const itemIndex = < T = unknown > ( id , items ) => { const item = findItem < T > ( id , items ) ; return item ? items . indexOf ( item ) : - 1 ; } ; const removeItem = < T = unknown > ( id , items ) => { const index = itemIndex < T > ( id , items ) ; if ( index !== - 1 ) { items . splice ( index , 1 ) ; } return items ; } ; export const createId = ( identityOptions , ns ) => [ ns , identityOptions . id , identityOptions . spawn ] . filter ( Boolean ) . join ( "-" ) ; const store = { initialState : { store : { } , } , actions : ( update ) => ( { /**
         * Add an item to the end of the list.
         */ add : < T extends unknown = unknown > ( ns , item ) => { update ( ( state ) => { const items = state . store [ ns ] || [ ] ; state . store [ ns ] = [ ... items , item as Dialogic . Item < unknown > ] ; if ( item . timer ) { item . timer . states . map ( ( ) => store . actions ( update ) . refresh ( ) ) ; } return state ; } ) ; } , /**
         * Removes the first item with a match on `id`.
         */ remove : ( ns , id ) => { update ( ( state ) => { const items = state . store [ ns ] || [ ] ; const remaining = removeItem ( id , items ) ; state . store [ ns ] = remaining ; return state ; } ) ; } , /**
         * Replaces the first item with a match on `id` with a newItem.
         */ replace : < T = unknown > ( ns , id , newItem ) => { update ( ( state ) => { const items = state . store [ ns ] || [ ] ; if ( items ) { const index = itemIndex ( id , items ) ; if ( index !== - 1 ) { items [ index ] = newItem as Dialogic . Item < unknown > ; state . store [ ns ] = [ ... items ] as Dialogic . Item < unknown > [ ] ; } } return state ; } ) ; } , /**
         * Removes all items within a namespace.
         */ removeAll : ( ns ) => { update ( ( state ) => { state . store [ ns ] = [ ] ; return state ; } ) ; } , /**
         * Replaces all items within a namespace.
         */ store : < T = unknown > ( ns , newItems ) => { update ( ( state ) => { state . store [ ns ] = [ ... ( newItems as Dialogic . Item [ ] ) ] ; return state ; } ) ; } , refresh : ( ) => { update ( ( state ) => ( { ... state , } ) ) ; } , } ) , selectors : ( states ) => { const fns = { getStore : ( ) => { const state = states ( ) ; return state . store ; } , find : < T = unknown > ( ns , identityOptions ) => { const state = states ( ) ; const items = state . store [ ns ] || [ ] ; const id = createId ( identityOptions , ns ) ; const item = items . find ( ( fitem ) => fitem . id === id ) as Dialogic . Item < T > ; return item ? { just : item } : { nothing : undefined } ; } , getAll : < T = unknown > ( ns , identityOptions ? ) => { const state = states ( ) ; const items = ( state . store [ ns ] || [ ] ) as Dialogic . Item < T > [ ] ; const spawn = identityOptions !== undefined ? identityOptions . spawn : undefined ; const id = identityOptions !== undefined ? identityOptions . id : undefined ; const itemsBySpawn = spawn !== undefined ? items . filter ( ( fitem ) => fitem . identityOptions . spawn === spawn ) : items ; const itemsById = id !== undefined ? itemsBySpawn . filter ( ( item ) => item . identityOptions . id === id ) : itemsBySpawn ; return itemsById ; } , getCount : ( ns , identityOptions ? ) => fns . getAll ( ns , identityOptions ) . length , } ; return fns ; } , } ; const update = Stream < PatchFn > ( ) ; export const states = Stream . scan ( ( state , patch ) => patch ( state ) , { ... store . initialState , } , update ) ; export const actions = { ... store . actions ( update ) , } ; export const selectors = { ... store . selectors ( states ) , } ;