74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { SmartDataDbDoc } from './classes.doc.js';
|
|
import * as plugins from './plugins.js';
|
|
import { EventEmitter } from 'events';
|
|
|
|
/**
|
|
* a wrapper for the native mongodb cursor. Exposes better
|
|
*/
|
|
/**
|
|
* Wraps a MongoDB ChangeStream with RxJS and EventEmitter support.
|
|
*/
|
|
export class SmartdataDbWatcher<T = any> extends EventEmitter {
|
|
// STATIC
|
|
public readyDeferred = plugins.smartpromise.defer();
|
|
|
|
// INSTANCE
|
|
private changeStream: plugins.mongodb.ChangeStream<T>;
|
|
private rawSubject: plugins.smartrx.rxjs.Subject<T>;
|
|
/** Emits change documents (or arrays of documents if buffered) */
|
|
public changeSubject: any;
|
|
/**
|
|
* @param changeStreamArg native MongoDB ChangeStream
|
|
* @param smartdataDbDocArg document class for instance creation
|
|
* @param opts.bufferTimeMs optional milliseconds to buffer events via RxJS
|
|
*/
|
|
constructor(
|
|
changeStreamArg: plugins.mongodb.ChangeStream<T>,
|
|
smartdataDbDocArg: typeof SmartDataDbDoc,
|
|
opts?: { bufferTimeMs?: number },
|
|
) {
|
|
super();
|
|
this.rawSubject = new plugins.smartrx.rxjs.Subject<T>();
|
|
// Apply buffering if requested
|
|
if (opts && opts.bufferTimeMs) {
|
|
this.changeSubject = this.rawSubject.pipe(plugins.smartrx.rxjs.ops.bufferTime(opts.bufferTimeMs));
|
|
} else {
|
|
this.changeSubject = this.rawSubject;
|
|
}
|
|
this.changeStream = changeStreamArg;
|
|
this.changeStream.on('change', async (item: any) => {
|
|
let docInstance: T = null;
|
|
if (item.fullDocument) {
|
|
docInstance = smartdataDbDocArg.createInstanceFromMongoDbNativeDoc(
|
|
item.fullDocument
|
|
) as any as T;
|
|
}
|
|
// Notify subscribers
|
|
this.rawSubject.next(docInstance);
|
|
this.emit('change', docInstance);
|
|
});
|
|
// Signal readiness after one tick
|
|
plugins.smartdelay.delayFor(0).then(() => {
|
|
this.readyDeferred.resolve();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Close the change stream, complete the RxJS subject, and remove listeners.
|
|
*/
|
|
public async close(): Promise<void> {
|
|
// Close MongoDB ChangeStream
|
|
await this.changeStream.close();
|
|
// Complete the subject to teardown any buffering operators
|
|
this.rawSubject.complete();
|
|
// Remove all EventEmitter listeners
|
|
this.removeAllListeners();
|
|
}
|
|
/**
|
|
* Alias for close(), matching README usage
|
|
*/
|
|
public async stop(): Promise<void> {
|
|
return this.close();
|
|
}
|
|
}
|