import { Serializable } from "./encoding" ; import { VaultItem } from "./item" ; /**
 * A collection of vault items items, used for consolidating changes made independently
 * across multiple instances through "merging".
 */ export class VaultItemCollection extends Serializable implements Iterable < VaultItem > { /** Number of items in this VaultItemCollection */ get size ( ) { return this . _items . size ; } get hasChanges ( ) { return ! ! this . _changes . size ; } /** Aggregated list of tags assigned to the items in this collection */ get tags ( ) : string [ ] { const tags = new Set < string > ( ) ; for ( const r of this ) { for ( const t of r . tags ) { tags . add ( t ) ; } } return [ ... tags ] ; } private _items : Map < string , VaultItem > ; private _changes = new Map < string , Date > ( ) ; constructor ( items = [ ] ) { super ( ) ; this . _items = new Map ( items . map ( item => [ item . id , item ] as [ string , VaultItem ] ) ) ; } /** Get an item with a given `id` */ get ( id ) { return this . _items . get ( id ) || null ; } /**
     * Updates one or more items based on their id. If no item with the same id
     * exists, the item will be added to the collection
     */ update ( ... items ) { for ( const item of items ) { item . updated = new Date ( ) ; this . _items . set ( item . id , item ) ; this . _changes . set ( item . id , item . updated ) ; } } /**
     * Removes one or more items based on their id.
     */ remove ( ... items ) { for ( const item of items ) { this . _items . delete ( item . id ) ; this . _changes . set ( item . id , new Date ( ) ) ; } } /**
     * Merges in changes from another [[VaultItemCollection]] instance.
     */ merge ( coll ) { for ( const item of this ) { if ( ! this . _changes . has ( item . id ) && ! coll . get ( item . id ) ) { this . _items . delete ( item . id ) ; } } for ( const item of coll ) { if ( ! this . _changes . has ( item . id ) ) { this . _items . set ( item . id , item ) ; } } } clearChanges ( before ? ) { for ( const [ id , changed ] of this . _changes . entries ( ) ) { if ( ! before || changed <= before ) { this . _changes . delete ( id ) ; } } } protected _toRaw ( version ) { return { items : Array . from ( this ) . map ( item => item . toRaw ( version ) ) , changes : [ ... this . _changes ] } ; } protected _fromRaw ( { items , changes } ) { this . _items = new Map ( items . map ( ( item ) => [ item . id , new VaultItem ( ) . fromRaw ( item ) ] as [ string , VaultItem ] ) ) ; this . _changes = new Map < string , Date > ( changes && changes . map ( ( [ id , date ] ) => [ id , new Date ( date ) ] ) ) ; } [ Symbol . iterator ] ( ) { return this . _items . values ( ) ; } }