@jsenv/server 10.0.3 → 10.0.4

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": "@jsenv/server",
3
- "version": "10.0.3",
3
+ "version": "10.0.4",
4
4
  "description": "Write your Node.js server using pure functions",
5
5
  "license": "MIT",
6
6
  "author": {
package/src/fetch_url.js CHANGED
@@ -4,10 +4,7 @@ import { Agent } from "node:https"
4
4
  import nodeFetch, { Response } from "node-fetch"
5
5
 
6
6
  import { fetchFileSystem } from "./fetch_filesystem.js"
7
- import {
8
- isFileHandle,
9
- fileHandleToReadableStream,
10
- } from "./internal/responseBody.js"
7
+ import { isFileHandle, fileHandleToReadableStream } from "./internal/body.js"
11
8
 
12
9
  export const fetchUrl = async (
13
10
  url,
@@ -4,7 +4,7 @@ import { createReadStream } from "node:fs"
4
4
  import { isObservable, observableFromValue } from "./observable.js"
5
5
  import { nodeStreamToObservable } from "./nodeStreamToObservable.js"
6
6
 
7
- export const normalizeResponseBodyMethods = (body) => {
7
+ export const normalizeBodyMethods = (body) => {
8
8
  if (isObservable(body)) {
9
9
  return {
10
10
  asObservable: () => body,
@@ -6,6 +6,24 @@ import { createObservable } from "./observable.js"
6
6
  const readableStreamLifetimeInSeconds = 120
7
7
 
8
8
  export const nodeStreamToObservable = (nodeStream) => {
9
+ const observable = createObservable(({ next, error, complete }) => {
10
+ const cleanup = () => {
11
+ nodeStream.removeListener("data", next)
12
+ nodeStream.removeListener("error", error)
13
+ nodeStream.removeListener("end", complete)
14
+ nodeStream.removeListener("close", cleanup)
15
+ nodeStream.destroy()
16
+ }
17
+
18
+ // should we do nodeStream.resume() in case the stream was paused ?
19
+ nodeStream.once("error", error)
20
+ nodeStream.on("data", next)
21
+ nodeStream.once("close", cleanup)
22
+ nodeStream.once("end", complete)
23
+
24
+ return cleanup
25
+ })
26
+
9
27
  if (nodeStream instanceof Readable) {
10
28
  // safe measure, ensure the readable stream gets
11
29
  // used in the next ${readableStreamLifetimeInSeconds} otherwise destroys it
@@ -20,28 +38,13 @@ export const nodeStreamToObservable = (nodeStream) => {
20
38
  )
21
39
  nodeStream.destroy()
22
40
  }, readableStreamLifetimeInSeconds * 1000)
41
+ observable.timeout = timeout
23
42
  onceReadableStreamUsedOrClosed(nodeStream, () => {
24
43
  clearTimeout(timeout)
25
44
  })
26
45
  }
27
46
 
28
- return createObservable(({ next, error, complete }) => {
29
- const cleanup = () => {
30
- nodeStream.removeListener("data", next)
31
- nodeStream.removeListener("error", error)
32
- nodeStream.removeListener("end", complete)
33
- nodeStream.removeListener("close", cleanup)
34
- nodeStream.destroy()
35
- }
36
-
37
- // should we do nodeStream.resume() in case the stream was paused ?
38
- nodeStream.once("error", error)
39
- nodeStream.on("data", next)
40
- nodeStream.once("close", cleanup)
41
- nodeStream.once("end", complete)
42
-
43
- return cleanup
44
- })
47
+ return observable
45
48
  }
46
49
 
47
50
  const onceReadableStreamUsedOrClosed = (readableStream, callback) => {
@@ -1,7 +1,7 @@
1
1
  import { Http2ServerResponse } from "node:http2"
2
2
  import { raceCallbacks } from "@jsenv/abort"
3
3
 
4
- import { normalizeResponseBodyMethods } from "./responseBody.js"
4
+ import { normalizeBodyMethods } from "./body.js"
5
5
 
6
6
  export const populateNodeResponse = async (
7
7
  responseStream,
@@ -9,7 +9,7 @@ export const populateNodeResponse = async (
9
9
  { signal, ignoreBody, onAbort, onError, onHeadersSent, onEnd } = {},
10
10
  ) => {
11
11
  body = await body
12
- const bodyMethods = normalizeResponseBodyMethods(body)
12
+ const bodyMethods = normalizeBodyMethods(body)
13
13
 
14
14
  if (signal.aborted) {
15
15
  bodyMethods.destroy()
@@ -636,6 +636,14 @@ export const startServer = async ({
636
636
  if (receiveRequestOperation.signal.aborted) {
637
637
  return
638
638
  }
639
+
640
+ // the node request readable stream is never closed because
641
+ // the response headers contains "connection: keep-alive"
642
+ // In this scenario we want to disable READABLE_STREAM_TIMEOUT warning
643
+ if (responseProperties.headers.connection === "keep-alive") {
644
+ clearTimeout(request.body.timeout)
645
+ }
646
+
639
647
  await sendResponse({
640
648
  signal: sendResponseOperation.signal,
641
649
  request,