import * as Datastore from "@google-cloud/datastore" ; import { BaseEntity } from "../BaseEntity" ; import { tsDatastoreOrm } from "../tsDatastoreOrm" ; import { updateStack } from "../utils" ; interface IAsyncIterator < T > { next ( value ? ) : Promise < IteratorResult < T [ ] > > ; } export class QueryAsyncIterator < T extends typeof BaseEntity > { public readonly query : Datastore . Query ; public readonly classObject : T ; public isClosed : boolean = false ; constructor ( options ) { this . query = options . query ; this . classObject = options . classObject ; } public close ( ) { this . isClosed = true ; } public [ Symbol . asyncIterator ] ( ) { return { next : async ( ) => { const friendlyErrorStack = tsDatastoreOrm . getFriendlyErrorStack ( ) ; try { if ( ! this . isClosed ) { const [ results , queryInfo ] = await this . query . run ( ) ; if ( queryInfo && queryInfo . endCursor ) { this . query . start ( queryInfo . endCursor ) ; } if ( results . length ) { const entities = [ ] ; for ( const data of results ) { const entity = await tsDatastoreOrm . loadEntity ( this . classObject , data ) ; entities . push ( entity ) ; } return { value : entities , done : false } ; } else { this . isClosed = true ; } } return { value : undefined as any , done : true } ; } catch ( err ) { throw Object . assign ( err , friendlyErrorStack && { stack : updateStack ( friendlyErrorStack , err ) } ) ; } } , } ; } }