UNPKG

blow-collection

Version:

Simple in memory collection with Rx / Observable interface.

98 lines (84 loc) 2.48 kB
'use strict'; import {Observable} from 'rxjs'; import {Query, QueryRaw, QueryWhere} from 'blow-query'; import {filter as buildFilter} from 'blow-filters'; import {isUndefined, isNumber} from 'util'; export function get(obj: any, key: string, defaultValue?: any): any { return obj[key] || defaultValue; } export function set(obj: any, key: string, value: any): any { obj[key] = value; return obj; } export function has(obj: any, key: string): boolean { return !isUndefined(get(obj, key)); } export function dropReference(obj) { return Object.assign({}, obj); } export function limit<T>(data$: Observable<T>, limit: number): Observable<T> { if (isNumber(limit) && limit > 0) { return data$.take(limit); } else { return data$; } } export function skip<T>(data$: Observable<T>, skip: number): Observable<T> { if (isNumber(skip)) { return data$.skip(skip); } else { return data$; } } export function sort<T>(data$: Observable<T>, sort: { [key: string]: number }): Observable<T> { if (Object.keys(sort).length) { return data$.toArray().mergeMap(rows => { const fields = Object.keys(sort); rows = rows.sort((rowA, rowB) => { for (const field of fields) { if (rowA[field] > rowB[field]) { return 1 * sort[field]; } else if (rowA[field] < rowB[field]) { return -1 * sort[field]; } } return 0; }); return Observable.from(rows); }); } else { return data$; } } export function prepareQuery(query: QueryRaw | Query): QueryRaw { if (isUndefined(query)) { query = {}; } if (query instanceof Query) { query = (<Query>query).toJSON(); } return <QueryRaw>query; } export function where<T>(data$: Observable<T>, where: QueryWhere, invert?: boolean): Observable<T> { invert = invert || false; if (!Object.keys(where).length) { return data$; } let filter; if (invert) { filter = row => !buildFilter(where)(row); } else { filter = buildFilter(where); } return data$.filter(filter); } export function filter<T>(data$: Observable<T>, query: QueryRaw | Query): Observable<T> { const defaultQuery = { where: {}, sort: {}, limit: -1, skip: 0 }; query = prepareQuery(query); const q: QueryRaw = Object.assign({}, defaultQuery, query); data$ = where(data$, q.where); data$ = sort(data$, q.sort); data$ = skip(data$, q.skip); data$ = limit(data$, q.limit); return data$; }