@middy/core 7.6.2 → 7.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // Copyright 2017 - 2026 will Farrell, Luciano Mammino, and Middy contributors.
2
2
  // SPDX-License-Identifier: MIT
3
3
  /* global awslambda */
4
- import { Readable } from "node:stream";
4
+ import { once } from "node:events";
5
5
  import { pipeline } from "node:stream/promises";
6
6
  import { ReadableStream } from "node:stream/web";
7
7
 
@@ -36,28 +36,21 @@ export const executionModeStreamifyResponse = (
36
36
  );
37
37
  }
38
38
 
39
- let handlerStream;
40
- if (handlerBody._readableState || handlerBody instanceof ReadableStream) {
41
- handlerStream = handlerBody;
42
- } else if (typeof handlerBody === "string") {
43
- // #1189
44
- handlerStream = Readable.from(
45
- handlerBody.length < stringIteratorSize
46
- ? handlerBody
47
- : stringIterator(handlerBody),
48
- );
49
- }
50
-
51
- if (!handlerStream) {
52
- throw new Error("handler response not a Readable or ReadableStream", {
53
- cause: { package: "@middy/core" },
54
- });
55
- }
56
-
57
39
  // See executionModeStandard for the .cause-chaining rationale.
58
40
  let handlerError;
59
41
  try {
60
- await pipeline(handlerStream, responseStream);
42
+ if (typeof handlerBody === "string") {
43
+ await writeString(responseStream, handlerBody);
44
+ } else if (
45
+ handlerBody._readableState ||
46
+ handlerBody instanceof ReadableStream
47
+ ) {
48
+ await pipeline(handlerBody, responseStream);
49
+ } else {
50
+ throw new Error("handler response not a Readable or ReadableStream", {
51
+ cause: { package: "@middy/core" },
52
+ });
53
+ }
61
54
  } catch (err) {
62
55
  handlerError = err;
63
56
  }
@@ -81,12 +74,32 @@ export const executionModeStreamifyResponse = (
81
74
  return middy;
82
75
  };
83
76
 
84
- const stringIteratorSize = 16384; // 16 * 1024 // Node.js default
85
- function* stringIterator(input) {
86
- let position = 0;
87
- const length = input.length;
88
- while (position < length) {
89
- yield input.substring(position, position + stringIteratorSize);
90
- position += stringIteratorSize;
77
+ // #1189 Streams the string body directly into the AWS Lambda response stream,
78
+ // bypassing Readable.from + pipeline. For sub-chunk strings this is a single
79
+ // write+end; for larger strings we slice and respect backpressure via `drain`.
80
+ const chunkSize = 16384; // 16 * 1024, matches Node.js default highWaterMark
81
+ const writeString = async (stream, body) => {
82
+ if (body.length <= chunkSize) {
83
+ // Single-shot: write triggers HttpResponseStream's prelude+delimiter
84
+ // on first write, then our body, then end(). Always write (even empty)
85
+ // so the prelude is flushed for zero-length bodies.
86
+ stream.write(body);
87
+ } else {
88
+ let position = 0;
89
+ const length = body.length;
90
+ while (position < length) {
91
+ const next = position + chunkSize;
92
+ const ok = stream.write(body.substring(position, next));
93
+ position = next;
94
+ if (!ok && position < length) {
95
+ await once(stream, "drain");
96
+ }
97
+ }
91
98
  }
92
- }
99
+ // stream.end(cb) calls cb on 'finish'; cb has no arg. Separate 'error'
100
+ // listener handles any late write errors so we don't hang on failure.
101
+ await new Promise((resolve, reject) => {
102
+ stream.once("error", reject);
103
+ stream.end(resolve);
104
+ });
105
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@middy/core",
3
- "version": "7.6.2",
3
+ "version": "7.6.3",
4
4
  "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
5
  "type": "module",
6
6
  "engines": {
@@ -76,14 +76,23 @@
76
76
  },
77
77
  "license": "MIT",
78
78
  "keywords": [
79
+ "Middy",
80
+ "middleware",
81
+ "middleware engine",
79
82
  "Lambda",
80
- "Middleware",
81
- "Serverless",
82
- "Framework",
83
83
  "AWS",
84
84
  "AWS Lambda",
85
+ "Serverless",
86
+ "Framework",
87
+ "Node.js",
88
+ "TypeScript",
89
+ "ESM",
90
+ "API Gateway",
85
91
  "Function URL",
86
- "Durable function"
92
+ "streamify-response",
93
+ "Durable function",
94
+ "event-driven",
95
+ "observability"
87
96
  ],
88
97
  "author": {
89
98
  "name": "Middy contributors",
@@ -103,7 +112,7 @@
103
112
  "url": "https://github.com/sponsors/willfarrell"
104
113
  },
105
114
  "dependencies": {
106
- "@middy/util": "7.6.2"
115
+ "@middy/util": "7.6.3"
107
116
  },
108
117
  "peerDependencies": {
109
118
  "@aws/durable-execution-sdk-js": "^1.0.0"