documentdb-typescript
Version:
TypeScript API for Microsoft Azure DocumentDB
101 lines (100 loc) • 5.41 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Util_1 = require("./Util");
// polyfill Symbol.asyncIterator
if (!Symbol.asyncIterator) {
Symbol.asyncIterator = Symbol("Symbol.asyncIterator");
}
/** Represents asynchronously loaded query result sets as a stream; the type parameter represents the query result type, i.e. a full document resource type for `SELECT * FROM` queries, an object with only projected properties for `SELECT x, y, ... FROM` queries, or even a scalar value for `SELECT VALUE ... FROM` queries */
class DocumentStream {
/** Private constructor */
constructor(_collection, _uid, _qiP) {
this._collection = _collection;
this._uid = _uid;
this._qiP = _qiP;
/** Timeout (ms) used for all operations; set to the Client timeout initially, set this to a large number if reading a large result set using `toArray` */
this.timeout = this._collection.database.client.timeout;
/** This property makes the entire instance usable as an async iterator */
this[Symbol.asyncIterator] = () => this;
/** @internal Promise for the last operation's result */
this._nextP = Promise.resolve(true);
// nothing here
}
/** @internal create a document stream from a query iterator promise */
static create(_collection, _uid, _qiP) {
return new DocumentStream(_collection, _uid, _qiP);
}
/** Get the next result (asynchronously), if any; promise resolves to the result, or to `null` if there are no results left in the set, or is rejected if an error occurred; subsequent calls to this function will return promises for results after the current result (i.e. requests are queued) */
read() {
return __awaiter(this, void 0, void 0, function* () {
var nextResult = yield this.next();
return nextResult.done ? null : nextResult.value;
});
}
/** Get the next result (asynchronously), if any; promise resolves to a `{ value, done }` pair, or is rejected if an error occurred; subsequent calls to this function will return promises for results after the current result (i.e. requests are queued) */
next() {
return __awaiter(this, void 0, void 0, function* () {
var qi = this._qi || (this._qi = yield this._qiP);
var readNextAsync = Util_1.curryPromise(qi.nextItem.bind(qi), this.timeout, 0, 100);
var next = yield (this._nextP = this._nextP.then(() => this._collection.database.client.log(`[>>${this._uid}] Reading from stream...`) &&
readNextAsync()));
return next !== undefined ?
{ value: next, done: false } :
{ value: undefined, done: true };
});
}
/** Call a function for each result, until all results have been processed or the callback returns `false` or throws an error; returned promise resolves to true if all results have been processed, or false otherwise, or is rejected if an error occurred */
forEach(f) {
let next = () => {
return this.next().then(n => {
if (n.done)
return true;
if (f(n.value) === false)
return false;
return next();
});
};
return next();
}
/** Call a function for each result; returns a promise for an array with all return values, which is resolved only when all results have been processed, or is rejected if the callback throws an error */
mapAsync(f) {
return __awaiter(this, void 0, void 0, function* () {
var result = [];
while (true) {
var n = yield this.next();
if (n.done)
return result;
result.push(f(n.value));
}
});
}
/** Reset the stream to the beginning of the set (synchronously); returns the stream itself */
reset() {
this._qi && this._qi.reset();
return this;
}
/** Reset the stream to the beginning of the set (asynchronously, i.e. after all queued operations have completed) */
resetAsync() {
return this._nextP.then(() => {
this._qi && this._qi.reset();
});
}
/** Load all results into an array */
toArray() {
return __awaiter(this, void 0, void 0, function* () {
var qi = this._qi || (this._qi = yield this._qiP);
var readArrayAsync = Util_1.curryPromise(qi.toArray.bind(qi), this.timeout, 0);
return yield (this._nextP = this._nextP.then(() => this._collection.database.client.log(`[>>${this._uid}] Reading into array from stream...`) &&
readArrayAsync()));
});
}
}
exports.DocumentStream = DocumentStream;