From c5c8aff34ea1e53345462264510dec0ca7098303 Mon Sep 17 00:00:00 2001
From: Jack Hsu <jack.hsu@gmail.com>
Date: Tue, 7 May 2024 21:16:25 -0400
Subject: [PATCH] fix(core): update getLastValueFromAsyncIterableIterator to
 support AsyncIterables returned from executors

---
 .../async-iterable/create-async-iterable.spec.ts     | 12 ++++++++++++
 packages/nx/src/utils/async-iterator.ts              |  8 ++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/packages/devkit/src/utils/async-iterable/create-async-iterable.spec.ts b/packages/devkit/src/utils/async-iterable/create-async-iterable.spec.ts
index faedf38e6224f..5b1f16862de32 100644
--- a/packages/devkit/src/utils/async-iterable/create-async-iterable.spec.ts
+++ b/packages/devkit/src/utils/async-iterable/create-async-iterable.spec.ts
@@ -1,4 +1,5 @@
 import { createAsyncIterable } from './create-async-iterable';
+import { getLastValueFromAsyncIterableIterator } from 'nx/src/utils/async-iterator';
 
 describe(createAsyncIterable.name, () => {
   test('simple callback', async () => {
@@ -55,4 +56,15 @@ describe(createAsyncIterable.name, () => {
 
     expect(results).toEqual(['first', 'second', 'third', 'fourth']);
   });
+
+  test('works with getLastValueFromAsyncIterableIterator', async () => {
+    const it = createAsyncIterable<string>(({ next, done }) => {
+      setTimeout(() => {
+        next('foo');
+        done();
+      });
+    });
+    const result = await getLastValueFromAsyncIterableIterator(it);
+    expect(result).toEqual('foo');
+  });
 });
diff --git a/packages/nx/src/utils/async-iterator.ts b/packages/nx/src/utils/async-iterator.ts
index af0f668dd760b..dd7030c1e0a11 100644
--- a/packages/nx/src/utils/async-iterator.ts
+++ b/packages/nx/src/utils/async-iterator.ts
@@ -3,13 +3,17 @@ export function isAsyncIterator<T>(v: any): v is AsyncIterableIterator<T> {
 }
 
 export async function getLastValueFromAsyncIterableIterator<T>(
-  i: AsyncIterableIterator<T>
+  i: AsyncIterable<T> | AsyncIterableIterator<T>
 ): Promise<T> {
   let prev: IteratorResult<T, T>;
   let current: IteratorResult<T, T>;
+
+  const generator = i[Symbol.asyncIterator] || i[Symbol.iterator];
+  const iterator = generator.call(i);
+
   do {
     prev = current;
-    current = await i.next();
+    current = await iterator.next();
   } while (!current.done);
 
   return current.value !== undefined || !prev ? current.value : prev.value;