This commit is contained in:
Jonasz Bigda
2023-03-25 21:51:42 +01:00
parent 0db1d5117e
commit b332e9ceb0
1044 changed files with 37502 additions and 63938 deletions

View File

@@ -8,7 +8,9 @@ const MongooseError = require('../error/mongooseError');
const Readable = require('stream').Readable;
const promiseOrCallback = require('../helpers/promiseOrCallback');
const eachAsync = require('../helpers/cursor/eachAsync');
const immediate = require('../helpers/immediate');
const util = require('util');
const utils = require('../../lib/utils');
/**
* An AggregationCursor is a concurrency primitive for processing aggregation
@@ -35,7 +37,14 @@ const util = require('util');
*/
function AggregationCursor(agg) {
Readable.call(this, { objectMode: true });
const streamOpts = { objectMode: true };
// for node < 12 we will emit 'close' event after 'end'
if (utils.nodeMajorVersion() >= 12) {
// set autoDestroy=true because on node 12 it's by default false
// gh-10902 need autoDestroy to destroy correctly and emit 'close' event for node >= 12
streamOpts.autoDestroy = true;
}
Readable.call(this, streamOpts);
this.cursor = null;
this.agg = agg;
@@ -85,13 +94,10 @@ AggregationCursor.prototype._read = function() {
if (error) {
return _this.emit('error', error);
}
setTimeout(function() {
// on node >= 14 streams close automatically (gh-8834)
const isNotClosedAutomatically = !_this.destroyed;
if (isNotClosedAutomatically) {
_this.emit('close');
}
}, 0);
// for node >= 12 the autoDestroy will emit the 'close' event
if (utils.nodeMajorVersion() < 12) {
_this.on('end', () => _this.emit('close'));
}
});
return;
}
@@ -125,7 +131,7 @@ if (Symbol.asyncIterator != null) {
* on('data', function(doc) { console.log(doc.foo); });
*
* // Or map documents returned by `.next()`
* var cursor = Thing.find({ name: /^hello/ }).
* const cursor = Thing.find({ name: /^hello/ }).
* cursor().
* map(function (doc) {
* doc.foo = "bar";
@@ -221,6 +227,56 @@ AggregationCursor.prototype.eachAsync = function(fn, opts, callback) {
return eachAsync(function(cb) { return _next(_this, cb); }, fn, opts, callback);
};
/**
* Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js
* You do not need to call this function explicitly, the JavaScript runtime
* will call it for you.
*
* ####Example
*
* // Async iterator without explicitly calling `cursor()`. Mongoose still
* // creates an AggregationCursor instance internally.
* const agg = Model.aggregate([{ $match: { age: { $gte: 25 } } }]);
* for await (const doc of agg) {
* console.log(doc.name);
* }
*
* // You can also use an AggregationCursor instance for async iteration
* const cursor = Model.aggregate([{ $match: { age: { $gte: 25 } } }]).cursor();
* for await (const doc of cursor) {
* console.log(doc.name);
* }
*
* Node.js 10.x supports async iterators natively without any flags. You can
* enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
*
* **Note:** This function is not set if `Symbol.asyncIterator` is undefined. If
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
* support async iterators.
*
* @method Symbol.asyncIterator
* @memberOf AggregationCursor
* @instance
* @api public
*/
if (Symbol.asyncIterator != null) {
AggregationCursor.prototype[Symbol.asyncIterator] = function() {
return this.transformNull()._transformForAsyncIterator();
};
}
/*!
* ignore
*/
AggregationCursor.prototype._transformForAsyncIterator = function() {
if (this._transforms.indexOf(_transformForAsyncIterator) === -1) {
this.map(_transformForAsyncIterator);
}
return this;
};
/*!
* ignore
*/
@@ -233,6 +289,14 @@ AggregationCursor.prototype.transformNull = function(val) {
return this;
};
/*!
* ignore
*/
function _transformForAsyncIterator(doc) {
return doc == null ? { done: true } : { value: doc, done: false };
}
/**
* Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag).
* Useful for setting the `noCursorTimeout` and `tailable` flags.
@@ -284,7 +348,7 @@ function _next(ctx, cb) {
}
if (ctx._error) {
return process.nextTick(function() {
return immediate(function() {
callback(ctx._error);
});
}