diff --git a/packages/minimongo/cursor.js b/packages/minimongo/cursor.js index 4db04d9734..1cdd2c88c1 100644 --- a/packages/minimongo/cursor.js +++ b/packages/minimongo/cursor.js @@ -216,6 +216,16 @@ export default class Cursor { return LocalCollection._observeFromObserveChanges(this, options); } + /** + * @summary observe async version + * @locus Anywhere + * @memberOf Promise + * @instance + */ + observeAsync(options) { + return new Promise(resolve => resolve(this.observe(options))); + } + /** * @summary Watch a query. Receive callbacks as the result set changes. Only * the differences between the old and new documents are passed to @@ -373,6 +383,19 @@ export default class Cursor { return handle; } + /** + * @summary observeChanges async version + * @locus Anywhere + * @memberOf Promise + * @instance + */ + observeChangesAsync(options) { + return new Promise((resolve) => { + const handle = this.observeChanges(options); + handle.isReadyPromise.then(() => resolve(handle)); + }); + } + // XXX Maybe we need a version of observe that just calls a callback if // anything changed. _depend(changers, _allow_unordered) { diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index 0ac003a35b..e92c40cf7c 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -940,6 +940,10 @@ Cursor.prototype.observe = function (callbacks) { return LocalCollection._observeFromObserveChanges(self, callbacks); }; +Cursor.prototype.observeAsync = function (callbacks) { + return new Promise(resolve => resolve(this.observe(callbacks))); +}; + Cursor.prototype.observeChanges = function (callbacks, options = {}) { var self = this; var methods = [ @@ -965,6 +969,10 @@ Cursor.prototype.observeChanges = function (callbacks, options = {}) { self._cursorDescription, ordered, callbacks, options.nonMutatingCallbacks); }; +Cursor.prototype.observeChangesAsync = async function (callbacks, options = {}) { + return this.observeChanges(callbacks, options); +}; + MongoConnection.prototype._createSynchronousCursor = function( cursorDescription, options) { var self = this; diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 4e50d5d507..413548caa1 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4302,3 +4302,40 @@ Tinytest.addAsync('mongo-livedata - maintained isomorphism using resolverType co test.equal(items, []); }); + +testAsyncMulti("mongo-livedata - support observeChangesAsync and observeAsync to keep isomorphism on client and server", [ + async (test) => { + const Collection = new Mongo.Collection(`observe_changes_async${test.runId()}`, { resolverType: 'stub' }); + const id = 'a'; + await Collection.insertAsync({ _id: id, foo: { bar: 123 } }); + + return new Promise(async resolve => { + const obs = await Collection.find(id).observeChangesAsync({ + async changed(_id, fields) { + await obs.stop(); + resolve(); + test.equal(_id, id); + test.equal(fields?.foo?.bar, 456); + }, + }); + await Collection.updateAsync(id, { $set: { 'foo.bar': 456 } }); + }); + }, + async (test) => { + const Collection = new Mongo.Collection(`observe_async${test.runId()}`, { resolverType: 'stub' }); + const id = 'a'; + await Collection.insertAsync({ _id: id, foo: { bar: 123 } }); + + return new Promise(async resolve => { + const obs = await Collection.find(id).observeAsync({ + async changed(newDocument) { + await obs.stop(); + test.equal(newDocument._id, id); + test.equal(newDocument?.foo?.bar, 456); + resolve(); + }, + }); + await Collection.updateAsync(id, { $set: { 'foo.bar': 456 } }); + }); + } +]);