import IterResult , { IterArgs } from './iterresult' ; import dateutil from './dateutil' ; import { isArray } from './helpers' ; export type CacheKeys = 'before' | 'after' | 'between' ; function argsMatch ( left , right ) { if ( Array . isArray ( left ) ) { if ( ! Array . isArray ( right ) ) return false ; if ( left . length !== right . length ) return false ; return left . every ( ( date , i ) => date . getTime ( ) === right [ i ] . getTime ( ) ) ; } if ( left instanceof Date ) { return right instanceof Date && left . getTime ( ) === right . getTime ( ) ; } return left === right ; } export class Cache { all : Date [ ] | Partial < IterArgs > | false = false ; before : IterArgs [ ] = [ ] ; after : IterArgs [ ] = [ ] ; between : IterArgs [ ] = [ ] ; param { String } what param { Array param { Object ? } args public _cacheAdd ( what , value , args ? ) { if ( value ) { value = value instanceof Date ? dateutil . clone ( value ) : dateutil . cloneDates ( value ) ; } if ( what === 'all' ) { this . all = value as Date [ ] ; } else { args ! . _value = value ; this [ what ] . push ( args as IterArgs ) ; } } return public _cacheGet ( what , args ? ) { let cached = false ; const argsKeys = args ? ( Object . keys ( args ) as ( keyof IterArgs ) [ ] ) : [ ] ; const findCacheDiff = function ( item ) { for ( let i = 0 ; i < argsKeys . length ; i ++ ) { const key = argsKeys [ i ] ; if ( ! argsMatch ( args ! [ key ] , item [ key ] ) ) { return true ; } } return false ; } ; const cachedObject = this [ what ] ; if ( what === 'all' ) { cached = this . all as Date [ ] ; } else if ( isArray ( cachedObject ) ) { for ( let i = 0 ; i < cachedObject . length ; i ++ ) { const item = cachedObject [ i ] as IterArgs ; if ( argsKeys . length && findCacheDiff ( item ) ) continue ; cached = item . _value ; break ; } } if ( ! cached && this . all ) { const iterResult = new IterResult ( what , args ! ) ; for ( let i = 0 ; i < ( this . all as Date [ ] ) . length ; i ++ ) { if ( ! iterResult . accept ( ( this . all as Date [ ] ) [ i ] ) ) break ; } cached = iterResult . getValue ( ) as Date ; this . _cacheAdd ( what , cached , args ) ; } return isArray ( cached ) ? dateutil . cloneDates ( cached ) : cached instanceof Date ? dateutil . clone ( cached ) : cached ; } }