@mantiq/heartbeat 0.1.0 → 0.1.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantiq/heartbeat",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Observability, APM & queue monitoring for MantiqJS",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -98,10 +98,11 @@ export class HeartbeatMiddleware implements Middleware {
98
98
  this.tracer.endRequest()
99
99
  }
100
100
 
101
- // Capture response data
101
+ // Capture response data (must rebuild response so body stays available for upstream middleware)
102
102
  if (this.requestWatcher && !error) {
103
103
  const responseHeaders = this.captureResponseHeaders(response!)
104
- const { body: responseBody, size: responseSize } = await this.captureResponseBody(response!)
104
+ const { body: responseBody, size: responseSize, rebuilt } = await this.captureResponseBody(response!)
105
+ if (rebuilt) response = rebuilt
105
106
 
106
107
  this.requestWatcher.recordRequest({
107
108
  method: request.method(),
@@ -168,7 +169,7 @@ export class HeartbeatMiddleware implements Middleware {
168
169
  return headers
169
170
  }
170
171
 
171
- private async captureResponseBody(response: Response): Promise<{ body: string | null; size: number | null }> {
172
+ private async captureResponseBody(response: Response): Promise<{ body: string | null; size: number | null; rebuilt: Response | null }> {
172
173
  const contentType = response.headers.get('content-type') ?? ''
173
174
 
174
175
  // Only capture JSON responses
@@ -176,23 +177,29 @@ export class HeartbeatMiddleware implements Middleware {
176
177
 
177
178
  if (!isCaptureable || !response.body) {
178
179
  const size = parseInt(response.headers.get('content-length') ?? '0', 10) || null
179
- return { body: null, size }
180
+ return { body: null, size, rebuilt: null }
180
181
  }
181
182
 
182
183
  try {
183
- // Clone and read the body
184
- const cloned = response.clone()
185
- const text = await cloned.text()
184
+ // Read the body text — this consumes the stream
185
+ const text = await response.text()
186
186
  const size = text.length
187
187
 
188
- // Truncate large responses
188
+ // Truncate large responses for logging
189
189
  const body = text.length > MAX_RESPONSE_BODY
190
190
  ? text.slice(0, MAX_RESPONSE_BODY) + `... (truncated, ${text.length} bytes total)`
191
191
  : text
192
192
 
193
- return { body, size }
193
+ // Rebuild the response so upstream middleware still has a body
194
+ const rebuilt = new Response(text, {
195
+ status: response.status,
196
+ statusText: response.statusText,
197
+ headers: response.headers,
198
+ })
199
+
200
+ return { body, size, rebuilt }
194
201
  } catch {
195
- return { body: null, size: null }
202
+ return { body: null, size: null, rebuilt: null }
196
203
  }
197
204
  }
198
205
  }