import { CurriedFunction2 , curry2 } from '@most/prelude' ; import { SessionStorageClearCommand , SessionStorageCommand , SessionStorageRemoveItemCommand , SessionStorageSetItemCommand , SessionStorageSource , } from './types' ; import { Stream , constant , drain , map , multicast , skipRepeats , startWith , tap , } from 'most' ; import { hold } from '@most/hold' ; export interface SessionStorageSinks { sessionStorage$ : Stream < SessionStorageCommand > ; } export interface SessionStorageSources { sessionStorage : SessionStorageSource ; } export function SessionStorage ( sinks ) { const { sessionStorage$ } = sinks ; const storage$ = multicast ( constant ( window . sessionStorage , tap ( storageAction , sessionStorage$ ) ) ) ; drain ( storage$ ) ; const getItem = createGetItem ( storage$ ) ; const length = createLength ( storage$ ) ; const sessionStorage = { getItem , length } ; return { sessionStorage } ; } export function clear ( ) { return { method : 'clear' } ; } export function removeItem ( key ) { return { method : 'removeItem' , key } ; } export const setItem = curry2 ( function setItem ( key , value ) : SessionStorageSetItemCommand { return { method : 'setItem' , key , value } ; } ) ; function storageAction ( command ) { if ( command . method === 'clear' ) window . sessionStorage . clear ( ) ; if ( command . method === 'removeItem' ) window . sessionStorage . removeItem ( command . key ) ; if ( command . method === 'setItem' ) window . sessionStorage . setItem ( command . key , command . value ) ; } function createGetItem ( storage$ ) { return function getItem ( key ) : Stream < string | null > { return hold ( skipRepeats ( map ( ( storage ) => storage . getItem ( key ) , startWith ( window . sessionStorage , storage$ ) ) ) ) ; } ; } function createLength ( storage$ ) { return function length ( ) : Stream < number > { return hold ( skipRepeats ( map ( ( storage ) => storage . length , startWith ( window . sessionStorage , storage$ ) ) ) ) ; } ; }