import { Awaitable , Storage , StorageListOptions , StorageListResult , StoredKeyMeta , StoredMeta , StoredValueMeta , defaultClock , millisToSeconds , } from "@miniflare/shared" ; import { listFilterMatch , listPaginate } from "./helpers" ; export abstract class LocalStorage extends Storage { protected constructor ( private readonly clock = defaultClock ) { super ( ) ; } abstract hasMaybeExpired ( key ) ; abstract getMaybeExpired < Meta > ( key ) ; abstract deleteMaybeExpired ( key ) ; abstract listAllMaybeExpired < Meta > ( ) ; private expired ( { expiration } , time = this . clock ( ) ) { return expiration !== undefined && expiration <= millisToSeconds ( time ) ; } async has ( key ) { const stored = await this . hasMaybeExpired ( key ) ; if ( stored === undefined ) return false ; if ( this . expired ( stored ) ) { await this . deleteMaybeExpired ( key ) ; return false ; } return true ; } async get < Meta = unknown > ( key ) { const stored = await this . getMaybeExpired < Meta > ( key ) ; if ( stored === undefined ) return undefined ; if ( this . expired ( stored ) ) { await this . deleteMaybeExpired ( key ) ; return undefined ; } return stored ; } async delete ( key ) { const stored = await this . hasMaybeExpired ( key ) ; const expired = stored !== undefined && this . expired ( stored ) ; const deleted = await this . deleteMaybeExpired ( key ) ; if ( ! deleted ) return false ; return ! expired ; } async list < Meta = unknown > ( options ? ) { const time = this . clock ( ) ; const deletePromises = [ ] ; let keys = await this . listAllMaybeExpired < Meta > ( ) ; keys = keys . filter ( ( stored ) => { if ( this . expired ( stored , time ) ) { deletePromises . push ( this . deleteMaybeExpired ( stored . name ) ) ; return false ; } return listFilterMatch ( options , stored . name ) ; } ) ; const res = listPaginate ( options , keys ) ; await Promise . all ( deletePromises ) ; return res ; } }