UNPKG

documentdb-typescript

Version:
101 lines (100 loc) 5.41 kB
"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;