From d21bfa96ae14a02716e6c91a45b005dc03057860 Mon Sep 17 00:00:00 2001 From: Swapnil Nagar Date: Fri, 6 Feb 2026 00:04:10 -0800 Subject: [PATCH 1/2] Adding the AsyncIterable type --- package-lock.json | 4 +-- test/http/HttpResponse.test.ts | 49 ++++++++++++++++++++++++++++++++++ types/http.d.ts | 3 ++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d54728d..49166ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.11.1", + "version": "4.11.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.11.1", + "version": "4.11.2", "license": "MIT", "dependencies": { "@azure/functions-extensions-base": "0.2.0", diff --git a/test/http/HttpResponse.test.ts b/test/http/HttpResponse.test.ts index bfe5469..d75df31 100644 --- a/test/http/HttpResponse.test.ts +++ b/test/http/HttpResponse.test.ts @@ -400,6 +400,55 @@ describe('HttpResponse', () => { }); expect(await res.text()).to.equal('Hello from stream'); }); + + it('AsyncIterable body', async () => { + // AsyncIterable is useful for streaming responses (e.g., AI chat responses) + const encoder = new TextEncoder(); + + async function* generateChunks(): AsyncIterable { + yield encoder.encode('Async '); + yield encoder.encode('iterable '); + yield encoder.encode('content'); + } + + const res = new HttpResponse({ + body: generateChunks(), + }); + expect(await res.text()).to.equal('Async iterable content'); + }); + + it('AsyncIterable body with multiple chunks', async () => { + const encoder = new TextEncoder(); + const chunks = ['chunk1', 'chunk2', 'chunk3']; + + async function* generateChunks(): AsyncIterable { + for (const chunk of chunks) { + yield encoder.encode(chunk); + } + } + + const res = new HttpResponse({ + body: generateChunks(), + }); + expect(await res.text()).to.equal('chunk1chunk2chunk3'); + }); + + it('AsyncIterable body with delayed chunks', async () => { + const encoder = new TextEncoder(); + + async function* generateDelayedChunks(): AsyncIterable { + yield encoder.encode('first'); + await new Promise((resolve) => setTimeout(resolve, 10)); + yield encoder.encode('second'); + await new Promise((resolve) => setTimeout(resolve, 10)); + yield encoder.encode('third'); + } + + const res = new HttpResponse({ + body: generateDelayedChunks(), + }); + expect(await res.text()).to.equal('firstsecondthird'); + }); }); describe('HttpHeadersInit types', () => { diff --git a/types/http.d.ts b/types/http.d.ts index 5373544..8e8ed73 100644 --- a/types/http.d.ts +++ b/types/http.d.ts @@ -12,7 +12,7 @@ import { InvocationContext } from './InvocationContext'; * Represents the body types that can be used in an HTTP response. * This is a local definition to avoid dependency on lib.dom. * Compatible with Node.js native Fetch API body types. - * Includes Node.js Readable streams for HTTP streaming scenarios. + * Includes Node.js Readable streams and AsyncIterable for HTTP streaming scenarios. */ export type HttpResponseBodyInit = | ReadableStream @@ -20,6 +20,7 @@ export type HttpResponseBodyInit = | Blob | ArrayBufferView | ArrayBuffer + | AsyncIterable | FormData | URLSearchParams | string From c6fc65b47939c3b1503ccd3e83984123e779571b Mon Sep 17 00:00:00 2001 From: Swapnil Nagar Date: Fri, 6 Feb 2026 00:32:08 -0800 Subject: [PATCH 2/2] Fixing linting issue --- test/http/HttpResponse.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/http/HttpResponse.test.ts b/test/http/HttpResponse.test.ts index d75df31..15cacad 100644 --- a/test/http/HttpResponse.test.ts +++ b/test/http/HttpResponse.test.ts @@ -406,6 +406,7 @@ describe('HttpResponse', () => { const encoder = new TextEncoder(); async function* generateChunks(): AsyncIterable { + await Promise.resolve(); yield encoder.encode('Async '); yield encoder.encode('iterable '); yield encoder.encode('content'); @@ -422,6 +423,7 @@ describe('HttpResponse', () => { const chunks = ['chunk1', 'chunk2', 'chunk3']; async function* generateChunks(): AsyncIterable { + await Promise.resolve(); for (const chunk of chunks) { yield encoder.encode(chunk); }