Created
July 22, 2019 22:44
-
-
Save alexeden/ae323676ded1b87081507a2c8973ce7d to your computer and use it in GitHub Desktop.
RxJS watchKeys operator for tracking added, removed, and persisted items within an object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Observable, Subscriber } from 'rxjs'; | |
| type Dictionary<T> = { | |
| [key: string]: T; | |
| }; | |
| export type AddedEvent<T> = { | |
| type: 'added'; | |
| value: T; | |
| }; | |
| export type PersistEvent<T> = { | |
| type: 'persist'; | |
| value: T[]; | |
| }; | |
| export type RemovedEvent<T> = { | |
| type: 'removed'; | |
| value: T; | |
| }; | |
| export type WatchKeysEvent<T> | |
| = AddedEvent<T> | |
| | PersistEvent<T> | |
| | RemovedEvent<T>; | |
| export const watchKeys = <T>() => { | |
| const items = new Map<string, T>(); | |
| return (source: Observable<Dictionary<T>>) => | |
| new Observable((observer: Subscriber<WatchKeysEvent<T>>) => | |
| source.subscribe(obj => { | |
| const keys = Object.keys(obj); | |
| const addedKeys = keys.filter(k => !items.has(k)); | |
| const removedKeys = [...items.keys()].filter(k => !keys.includes(k)); | |
| // Process the keys that were added since last event | |
| addedKeys.map(k => obj[k]).forEach(value => observer.next({ type: 'added', value })); | |
| // Process the keys that were removed since last event | |
| removedKeys.map(k => items.get(k) as T).forEach(value => observer.next({ type: 'removed', value })); | |
| // Emit the persisted objects | |
| observer.next({ | |
| type: 'persist', | |
| value: keys.filter(k => !addedKeys.includes(k) && !removedKeys.includes(k)).map(k => obj[k]), | |
| }); | |
| // Reset and update the tracking map | |
| items.clear(); | |
| keys.forEach(id => items.set(id, obj[id])); | |
| }) | |
| ); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment