File

lib/common/src/meta-store/meta-store.class.ts

Index

Properties
Methods
Accessors

Constructor

constructor(stores: S[], metaActions: MetaAction[])
Parameters :
Name Type Optional
stores S[] No
metaActions MetaAction<C, I, S>[] No

Properties

Public change$
Type : Observable<I>
Public metaActions
Type : MetaAction<C, I, S>[]
Default value : []
Abstract name
Type : string
Public stores
Type : S[]
Default value : []

Methods

Async filter
filter(callback: (item: I,index: number,arr: I[]) => void)
Parameters :
Name Type Optional
callback function No
Returns : Promise<I[]>
Public Async get
get(id: string)
Parameters :
Name Type Optional
id string No
Returns : Promise<I | null>
Public Async get
get(ids: string[])
Parameters :
Name Type Optional
ids string[] No
Returns : Promise<[]>
Public Async get
get(id_or_ids: string | string[])
Parameters :
Name Type Optional
id_or_ids string | string[] No
Returns : Promise<[] | >
Public Async get
get(id_or_ids: string | string[])
Parameters :
Name Type Optional
id_or_ids string | string[] No
Returns : Promise<[] | >
Public getStore
getStore(item: I)
Parameters :
Name Type Optional
item I No
Returns : S | null
Public handleIdWithoutItem
handleIdWithoutItem(id: string)
Parameters :
Name Type Optional
id string No
Returns : I | null

Accessors

items
getitems()
ready
getready()
import	{	Item,
			ItemConfig,
			ItemStore,
		}							from '@rcc/core'

import	{
			Observable,
			merge
		}							from 'rxjs'

import	{
			share
		}							from 'rxjs/operators'

import	{	
			MetaAction	
		}							from './meta-store.commons'


export abstract	class MetaStore
				<
					C extends ItemConfig 	= unknown,
					I extends Item<C>		= Item<C>,
					S extends ItemStore<I>	= ItemStore<I>
				> {

	abstract	name 			: string

	public		change$			: Observable<I>


	constructor(		
		public stores			: S[]					= [],
		public metaActions		: MetaAction<C,I,S>[]	= []	
	) {

		this.stores 		= stores 		|| []
		this.metaActions	= metaActions	|| []

		this.change$		= 	merge(...this.stores.map( store => store.change$ ))
								.pipe( share() )
	}

	get items() : I[] {

		const array_of_items 	= this.stores.map( store => store.items).flat()
		const unique_items		= new Array<I>()
		const ids				= new Array<string>()

		array_of_items.forEach( item => {
			if(!item.id) 				return unique_items.push(item)
			if(ids.includes(item.id))	return null

			ids.push(item.id)
			unique_items.push(item)
		})

		if(array_of_items.length != unique_items.length) console.warn("MetaStore.items: duplicate item IDs!" )

		return unique_items
	}

	get ready() : Promise<unknown[]>{

		return 	Promise.all( this.stores.map( store => store.ready) )

	}

	public handleIdWithoutItem(id: string): I | null {
		return null
	}

	public async get (id: string): Promise<I | null>
	public async get (ids: string[]): Promise<( I | null)[]>
	public async get (id_or_ids: string | string []): Promise<(I|null)[]|(I|null)>
	public async get (id_or_ids: string | string []): Promise<(I|null)[]|(I|null)> {

		if(typeof id_or_ids == 'string') return await this.get([id_or_ids]).then( items => items[0])

		const 	getPromises	= 	this.stores.map( store => store.get(id_or_ids) ) //TODO: deal with doubles?
		const 	itemArrays 	= 	await Promise.all(getPromises)  //TODO: deal with undefined!

		const	result 		= 	id_or_ids.map( (id: string, index: number) => {
			
									return 	itemArrays.reduce( (result:I | null, itemArray: (I | null)[])  => {
												return result || itemArray[index]
											}, null )
											||
											this.handleIdWithoutItem(id)

								})
								.filter( (item: I | null ) => item != null )
		
		return result
		
	}

	public getStore(item: I) : S | null {
		return 	this.stores.find( (store: S) =>  store.items.includes(item) ) || null
	}


	async filter( callback: (item :I, index?:number, arr?: I[]) => boolean ) : Promise<I[]> {
		await this.ready

		return 	this.items
				.filter(callback)

	}

}

results matching ""

    No results matching ""