@mastra/fastify 1.3.19-alpha.1 → 1.3.19-alpha.10

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/dist/index.js CHANGED
@@ -304,9 +304,12 @@ function toWebRequest2(request) {
304
304
  headers
305
305
  });
306
306
  }
307
+ function isRequestAborted(rawRequest) {
308
+ return rawRequest.aborted || rawRequest.readableAborted || !rawRequest.complete;
309
+ }
307
310
  var MastraServer = class extends MastraServer$1 {
308
311
  createContextMiddleware() {
309
- return async (request, _reply) => {
312
+ return async (request, reply) => {
310
313
  let bodyRequestContext;
311
314
  let paramsRequestContext;
312
315
  if (request.method === "POST" || request.method === "PUT") {
@@ -337,6 +340,13 @@ var MastraServer = class extends MastraServer$1 {
337
340
  }
338
341
  }
339
342
  const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });
343
+ this.applyRequestMetadataToContext({
344
+ requestContext,
345
+ getHeader: (name) => {
346
+ const value = request.headers[name.toLowerCase()];
347
+ return Array.isArray(value) ? value[0] : value;
348
+ }
349
+ });
340
350
  request.requestContext = requestContext;
341
351
  request.mastra = this.mastra;
342
352
  request.registeredTools = this.tools || {};
@@ -346,14 +356,19 @@ var MastraServer = class extends MastraServer$1 {
346
356
  request.customRouteAuthConfig = this.customRouteAuthConfig;
347
357
  const controller = new AbortController();
348
358
  request.raw.on("close", () => {
349
- if (!request.raw.complete) {
359
+ if (isRequestAborted(request.raw)) {
360
+ controller.abort();
361
+ }
362
+ });
363
+ reply.raw.on("close", () => {
364
+ if (!reply.raw.writableEnded) {
350
365
  controller.abort();
351
366
  }
352
367
  });
353
368
  request.abortSignal = controller.signal;
354
369
  };
355
370
  }
356
- async stream(route, reply, result) {
371
+ async stream(route, reply, result, request) {
357
372
  const rawHeaders = reply.getHeaders();
358
373
  const existingHeaders = {};
359
374
  for (const [key, value] of Object.entries(rawHeaders)) {
@@ -379,9 +394,20 @@ var MastraServer = class extends MastraServer$1 {
379
394
  });
380
395
  const readableStream = result instanceof ReadableStream ? result : result.fullStream;
381
396
  const reader = readableStream.getReader();
382
- reply.raw.on("close", () => {
383
- void reader.cancel("request aborted");
384
- });
397
+ let readerCanceled = false;
398
+ const cancelReader = (reason) => {
399
+ if (readerCanceled) return;
400
+ readerCanceled = true;
401
+ void reader.cancel(reason);
402
+ };
403
+ const cancelReaderOnResponseClose = () => cancelReader("request aborted");
404
+ const cancelReaderOnRequestClose = () => {
405
+ if (request && isRequestAborted(request.raw)) {
406
+ cancelReader("request aborted");
407
+ }
408
+ };
409
+ reply.raw.on("close", cancelReaderOnResponseClose);
410
+ request?.raw.on("close", cancelReaderOnRequestClose);
385
411
  try {
386
412
  while (true) {
387
413
  const { done, value } = await reader.read();
@@ -403,7 +429,11 @@ var MastraServer = class extends MastraServer$1 {
403
429
  error: error instanceof Error ? { message: error.message, stack: error.stack } : error
404
430
  });
405
431
  } finally {
406
- reply.raw.end();
432
+ reply.raw.off("close", cancelReaderOnResponseClose);
433
+ request?.raw.off("close", cancelReaderOnRequestClose);
434
+ if (!reply.raw.writableEnded && !reply.raw.destroyed) {
435
+ reply.raw.end();
436
+ }
407
437
  }
408
438
  }
409
439
  async getParams(route, request) {
@@ -498,20 +528,34 @@ var MastraServer = class extends MastraServer$1 {
498
528
  if (route.responseType === "json") {
499
529
  await reply.send(result);
500
530
  } else if (route.responseType === "stream") {
501
- await this.stream(route, reply, result);
531
+ await this.stream(route, reply, result, request);
502
532
  } else if (route.responseType === "datastream-response") {
503
533
  const fetchResponse = result;
504
534
  fetchResponse.headers.forEach((value, key) => reply.header(key, value));
505
535
  reply.status(fetchResponse.status);
506
536
  if (fetchResponse.body) {
507
537
  const reader = fetchResponse.body.getReader();
538
+ let readerCanceled = false;
539
+ const cancelReader = (reason) => {
540
+ if (readerCanceled) return;
541
+ readerCanceled = true;
542
+ void reader.cancel(reason);
543
+ };
544
+ const cancelReaderOnResponseClose = () => cancelReader("request aborted");
545
+ const cancelReaderOnRequestClose = () => {
546
+ if (request && isRequestAborted(request.raw)) {
547
+ cancelReader("request aborted");
548
+ }
549
+ };
508
550
  const onResError = (err) => {
509
551
  this.mastra.getLogger()?.error("Error writing datastream response", {
510
552
  error: err instanceof Error ? { message: err.message, stack: err.stack } : err
511
553
  });
512
- void reader.cancel("response write error");
554
+ cancelReader("response write error");
513
555
  };
514
556
  reply.raw.once("error", onResError);
557
+ reply.raw.on("close", cancelReaderOnResponseClose);
558
+ request?.raw.on("close", cancelReaderOnRequestClose);
515
559
  try {
516
560
  while (true) {
517
561
  const { done, value } = await reader.read();
@@ -524,7 +568,11 @@ var MastraServer = class extends MastraServer$1 {
524
568
  });
525
569
  } finally {
526
570
  reply.raw.off("error", onResError);
527
- reply.raw.end();
571
+ reply.raw.off("close", cancelReaderOnResponseClose);
572
+ request?.raw.off("close", cancelReaderOnRequestClose);
573
+ if (!reply.raw.writableEnded && !reply.raw.destroyed) {
574
+ reply.raw.end();
575
+ }
528
576
  }
529
577
  } else {
530
578
  reply.raw.end();