Repository: unjs/h3 (ts)

Issue:
fix sendProxy function
### Environment

nuxt 3 with nitro 2.4.0, node v18.14.2

### Reproduction

https://stackblitz.com/edit/github-xzp2dt?file=nuxt.config.ts,app.vue

### Describe the bug

It seems sendProxy function doesn't respond with correct data

I investigated this issue here: https://github.com/unjs/nitro/issues/1237

when loading images, 304 response and blob data are not handled correctly

this is the cause: https://github.com/unjs/h3/blob/2cbcb7d4bd5a2c50d316de5b23ed7124bf0bfe68/src/utils/proxy.ts#L109

### Additional context

I managed to fix it locally by using this change (probably not a good solution, just wanted to make it work):

```js
if (response._data !== undefined) {
    if (response._data && response._data.arrayBuffer) {
      await response._data.arrayBuffer().then(b => {
        const buffer = Buffer.from(b);
        event.node.res.write(buffer);
      });
    }
    return event.node.res.end();
  }
```

edit: updated solution (took from the code below it):
```js
if (response._data !== undefined) {
  if (response._data && response._data.arrayBuffer) {
      const data = new Uint8Array(await response._data.arrayBuffer());
      return event.node.res.end(data);
    }
    return response._data;
 }
```


### Logs

_No response_

Pull request description:
feat: support blob responses
Resolves #385 and https://github.com/unjs/nitro/issues/1237

Patch:
diff --git a/src/app.ts b/src/app.ts
index 1520fcb..c06d716 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -135,6 +135,15 @@ export function createAppEventHandler(stack: Stack, options: AppOptions) {
           return send(event, val);
         }
 
+        // Blob
+        if (val.arrayBuffer && typeof val.arrayBuffer === "function") {
+          return send(
+            event,
+            Buffer.from(await (val as Blob).arrayBuffer()),
+            val.type
+          );
+        }
+
         // Error
         if (val instanceof Error) {
           throw createError(val);


Test patch:
diff --git a/test/app.test.ts b/test/app.test.ts
index df56deb..2886cc5 100644
--- a/test/app.test.ts
+++ b/test/app.test.ts
@@ -10,8 +10,9 @@ import {
   createError,
 } from "../src";
 
-const readableStreamSupported =
-  typeof ReadableStream !== "undefined"; /* Node.js 16 */
+// Node.js 16 limitations
+const readableStreamSupported = typeof ReadableStream !== "undefined";
+const blobSupported = typeof Blob !== "undefined";
 
 describe("app", () => {
   let app: App;
@@ -55,6 +56,21 @@ describe("app", () => {
     }
   });
 
+  it.runIf(blobSupported)("can return Blob directly", async () => {
+    app.use(
+      eventHandler(
+        () =>
+          new Blob(["<h1>Hello World</h1>"], {
+            type: "text/html",
+          })
+      )
+    );
+    const res = await request.get("/");
+
+    expect(res.headers["content-type"]).toBe("text/html");
+    expect(res.text).toBe("<h1>Hello World</h1>");
+  });
+
   it("can return Buffer directly", async () => {
     app.use(eventHandler(() => Buffer.from("<h1>Hello world!</h1>", "utf8")));
     const res = await request.get("/");