import { ISourceCache } from './ISourceCache'; import { ISourceUpdater } from './ISourceUpdater'; import { Observable } from 'rxjs'; import { Change } from './Change'; import { IChangeSet } from './IChangeSet'; import { ObservableCache } from './ObservableCache'; import { EqualityComparer } from '../util/isEqualityComparer'; import { ArrayOrIterable } from '../util/ArrayOrIterable'; /** * An observable cache which exposes an update API. Used at the root * of all observable chains * @typeparam TObject The type of the object * @typeparam TKey The type of the key */ export class SourceCache implements ISourceCache { private readonly _innerCache: ObservableCache; /** * Initializes a new instance of the class. * @param keySelector The key selector. * @param deepEqual Use deep equal comparisons */ public constructor(keySelector: (value: TObject) => TKey, deepEqual = false) { this._innerCache = new ObservableCache(keySelector, deepEqual); } [Symbol.toStringTag]: 'ObservableCache' = 'ObservableCache'; edit(updateAction: (updater: ISourceUpdater) => void): void { this._innerCache.updateFromSource(updateAction); } watch(key: TKey): Observable> { return this._innerCache.watch(key); } connect(predicate?: ((object: TObject) => boolean) | undefined): Observable> { return this._innerCache.connect(predicate); } preview(predicate?: ((object: TObject) => boolean) | undefined): Observable> { return this._innerCache.preview(predicate); } get countChanged() { return this._innerCache.countChanged; } keys(): IterableIterator { return this._innerCache.keys(); } values(): IterableIterator { return this._innerCache.values(); } entries(): IterableIterator<[TKey, TObject]> { return this._innerCache.entries(); } lookup(key: TKey): TObject | undefined { return this._innerCache.lookup(key); } get size() { return this._innerCache.size; } [Symbol.iterator](): IterableIterator<[TKey, TObject]> { return this._innerCache[Symbol.iterator](); } dispose(): void { this._innerCache.dispose(); } getKey(item: TObject) { return this._innerCache.getKey(item); } } export function updateable(sourceCache: ISourceCache): ISourceCache & ISourceUpdater { return new SimpleSourceCache(sourceCache); } class SimpleSourceCache implements ISourceCache, ISourceUpdater { constructor(private readonly _sourceCache: ISourceCache) {} [Symbol.toStringTag]: 'ObservableCache' = 'ObservableCache'; edit(updateAction: (updater: ISourceUpdater) => void): void { return this._sourceCache.edit(updateAction); } watch(key: TKey): Observable> { return this._sourceCache.watch(key); } connect(predicate?: ((object: TObject) => boolean) | undefined): Observable> { return this._sourceCache.connect(predicate); } preview(predicate?: ((object: TObject) => boolean) | undefined): Observable> { return this._sourceCache.preview(predicate); } get countChanged() { return this._sourceCache.countChanged; } keys(): IterableIterator { return this._sourceCache.keys(); } values(): IterableIterator { return this._sourceCache.values(); } entries(): IterableIterator<[TKey, TObject]> { return this._sourceCache.entries(); } lookup(key: TKey): TObject | undefined { return this._sourceCache.lookup(key); } get size() { return this._sourceCache.size; } [Symbol.iterator](): IterableIterator<[TKey, TObject]> { return this._sourceCache[Symbol.iterator](); } dispose(): void { return this._sourceCache.dispose(); } addOrUpdate(item: TObject): void; addOrUpdate(item: TObject, comparer: EqualityComparer): void; addOrUpdate(item: TObject, key: TKey): void; addOrUpdate(item: TObject, comparer?: EqualityComparer | TKey): void { return this._sourceCache.edit(updater => updater.addOrUpdate(item, comparer as any)); } addOrUpdatePairs(entries: Array<[TKey, TObject]> | Iterable<[TKey, TObject]>): void { return this._sourceCache.edit(updater => updater.addOrUpdatePairs(entries)); } addOrUpdateValues(entries: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.addOrUpdateValues(entries)); } clear(): void { return this._sourceCache.edit(updater => updater.clear()); } clone(changes: IChangeSet): void { return this._sourceCache.edit(updater => updater.clone(changes)); } getKey(item: TObject): TKey { return this._sourceCache.getKey(item); } load(entries: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.load(entries)); } refresh(): void; refresh(item: TObject): void; refresh(item?: TObject): void { return this._sourceCache.edit(updater => updater.refresh(item as any)); } refreshKey(key: TKey): void { return this._sourceCache.edit(updater => updater.refreshKey(key)); } refreshKeys(keys: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.refreshKeys(keys)); } refreshValues(entries: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.refreshValues(entries)); } remove(item: TObject): void { return this._sourceCache.edit(updater => updater.remove(item)); } removeKey(key: TKey): void { return this._sourceCache.edit(updater => updater.removeKey(key)); } removeKeys(key: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.removeKeys(key)); } removePairs(entries: Array<[TKey, TObject]> | Iterable<[TKey, TObject]>): void { return this._sourceCache.edit(updater => updater.removePairs(entries)); } removeValues(entries: ArrayOrIterable): void { return this._sourceCache.edit(updater => updater.removeValues(entries)); } }