All files / src/mongodb/functions observable.model.ts

85.71% Statements 24/28
100% Branches 4/4
70% Functions 7/10
84% Lines 21/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70        10x 10x   10x             3x 3x   3x               3x         3x     3x   2x   1x                 11x 11x       11x 11x   11x 11x   11x           1x       11x 10x  
'use strict';
 
import {Model} from 'mongoose';
 
import {Subject, Subscription} from 'rxjs';
import {filter} from 'rxjs/operators';
 
import observableDatabase from './observable.database';
 
class ObservableModel extends Subject<any> {
	private readonly _collection: string;
	protected _subscription: Subscription;
 
	constructor(collection: string) {
		super();
		this._collection = collection;
 
		this._subscription = observableDatabase()
			.pipe(filter((change) => this._pipeFilter(change)))
			.subscribe({
				next: (change: any): void => {
					const {ns, documentKey, operationType, updateDescription, fullDocument} = change;
					this.next({ns, documentKey, operationType, updateDescription, fullDocument});
				},
				error: (e: any): void => this.error(e),
				complete: (): void => this.complete()
			});
	}
 
	private _pipeFilter(change: any): boolean {
		try {
			const {
				ns: {coll}
			} = change;
 
			return this._collection === coll;
		} catch (error) {
			return false;
		}
	}
}
 
class ObservableModelsMap {
	private static _instance: ObservableModelsMap;
 
	public static init(): ObservableModelsMap {
		if (!ObservableModelsMap._instance) ObservableModelsMap._instance = new ObservableModelsMap();
		return ObservableModelsMap._instance;
	}
 
	public static get(model: Model<any>): ObservableModel {
		const instance: ObservableModelsMap = ObservableModelsMap.init();
		const map: Map<string, ObservableModel> = instance._map;
 
		const collectionName: string = model.collection.collectionName;
		if (!map.get(collectionName)) map.set(collectionName, new ObservableModel(collectionName));
 
		return map.get(collectionName);
	}
 
	private readonly _map: Map<string, ObservableModel>;
 
	private constructor() {
		this._map = new Map<string, ObservableModel>();
	}
}
 
const observableModel = (model: Model<any>): Subject<any> => ObservableModelsMap.get(model);
export default observableModel;