@jsenv/server 12.7.0 → 12.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/server",
3
- "version": "12.7.0",
3
+ "version": "12.7.3",
4
4
  "description": "Write your Node.js server using pure functions",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -35,9 +35,10 @@
35
35
  "test": "node --conditions=development ./scripts/test.mjs"
36
36
  },
37
37
  "dependencies": {
38
- "@jsenv/abort": "4.2.2",
39
- "@jsenv/logger": "4.1.1",
40
- "@jsenv/url-meta": "7.0.0"
38
+ "@jsenv/abort": "4.2.3",
39
+ "@jsenv/log": "2.1.0",
40
+ "@jsenv/url-meta": "7.0.0",
41
+ "@jsenv/utils": "2.0.1"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@jsenv/fetch": "../fetch/",
@@ -4,23 +4,17 @@
4
4
  * It is meant to be used inside "requestToResponse"
5
5
  */
6
6
 
7
- import { createReadStream, statSync, promises } from "node:fs"
8
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
9
-
10
- import {
11
- isFileSystemPath,
12
- urlToFileSystemPath,
13
- fileSystemPathToUrl,
14
- } from "@jsenv/server/src/internal/filesystem.js"
15
- import { bufferToEtag } from "@jsenv/server/src/internal/etag.js"
7
+ import { createReadStream, statSync, readFile } from "node:fs"
8
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
9
+
10
+ import { isFileSystemPath, fileSystemPathToUrl } from "./internal/filesystem.js"
11
+ import { bufferToEtag } from "./internal/etag.js"
16
12
  import { composeTwoResponses } from "./internal/response_composition.js"
17
13
  import { convertFileSystemErrorToResponseProperties } from "./internal/convertFileSystemErrorToResponseProperties.js"
18
14
  import { timeFunction } from "./server_timing/timing_measure.js"
19
15
  import { negotiateContentEncoding } from "./content_negotiation/negotiateContentEncoding.js"
20
16
  import { serveDirectory } from "./serve_directory.js"
21
17
 
22
- const ETAG_MEMORY_MAP = new Map()
23
-
24
18
  export const fetchFileSystem = async (
25
19
  filesystemUrl,
26
20
  {
@@ -95,13 +89,11 @@ export const fetchFileSystem = async (
95
89
  }
96
90
  }
97
91
 
98
- let sourceUrl = `file://${new URL(urlString).pathname}`
99
- const sourceFilesystemPath = urlToFileSystemPath(filesystemUrl)
100
-
92
+ const sourceUrl = `file://${new URL(urlString).pathname}`
101
93
  try {
102
94
  const [readStatTiming, sourceStat] = await timeFunction(
103
95
  "file service>read file stat",
104
- () => statSync(sourceFilesystemPath),
96
+ () => statSync(new URL(sourceUrl)),
105
97
  )
106
98
  if (sourceStat.isDirectory()) {
107
99
  if (canReadDirectory) {
@@ -283,6 +275,7 @@ const getEtagResponse = async ({
283
275
  }
284
276
  }
285
277
 
278
+ const ETAG_MEMORY_MAP = new Map()
286
279
  const computeEtag = async ({
287
280
  etagMemory,
288
281
  etagMemoryMaxSize,
@@ -298,9 +291,15 @@ const computeEtag = async ({
298
291
  return etagMemoryEntry.eTag
299
292
  }
300
293
  }
301
- const fileContentAsBuffer = await promises.readFile(
302
- urlToFileSystemPath(sourceUrl),
303
- )
294
+ const fileContentAsBuffer = await new Promise((resolve, reject) => {
295
+ readFile(new URL(sourceUrl), (error, buffer) => {
296
+ if (error) {
297
+ reject(error)
298
+ } else {
299
+ resolve(buffer)
300
+ }
301
+ })
302
+ })
304
303
  const eTag = bufferToEtag(fileContentAsBuffer)
305
304
  if (etagMemory) {
306
305
  if (ETAG_MEMORY_MAP.size >= etagMemoryMaxSize) {
@@ -386,20 +385,23 @@ const getCompressedResponse = async ({ sourceUrl, headers }) => {
386
385
  }
387
386
 
388
387
  const fileUrlToReadableStream = (fileUrl) => {
389
- return createReadStream(urlToFileSystemPath(fileUrl), { emitClose: true })
388
+ return createReadStream(new URL(fileUrl), {
389
+ emitClose: true,
390
+ autoClose: true,
391
+ })
390
392
  }
391
393
 
392
394
  const availableCompressionFormats = {
393
395
  br: async (fileReadableStream) => {
394
- const { createBrotliCompress } = await import("zlib")
396
+ const { createBrotliCompress } = await import("node:zlib")
395
397
  return fileReadableStream.pipe(createBrotliCompress())
396
398
  },
397
399
  deflate: async (fileReadableStream) => {
398
- const { createDeflate } = await import("zlib")
400
+ const { createDeflate } = await import("node:zlib")
399
401
  return fileReadableStream.pipe(createDeflate())
400
402
  },
401
403
  gzip: async (fileReadableStream) => {
402
- const { createGzip } = await import("zlib")
404
+ const { createGzip } = await import("node:zlib")
403
405
  return fileReadableStream.pipe(createGzip())
404
406
  },
405
407
  }
@@ -69,7 +69,7 @@ const createSecureServer = async ({
69
69
  http1Allowed,
70
70
  }) => {
71
71
  if (http2) {
72
- const { createSecureServer } = await import("http2")
72
+ const { createSecureServer } = await import("node:http2")
73
73
  return createSecureServer({
74
74
  cert: certificate,
75
75
  key: privateKey,
@@ -77,7 +77,7 @@ const createSecureServer = async ({
77
77
  })
78
78
  }
79
79
 
80
- const { createServer } = await import("https")
80
+ const { createServer } = await import("node:https")
81
81
  return createServer({
82
82
  cert: certificate,
83
83
  key: privateKey,
@@ -1,6 +1,6 @@
1
- import { timeFunction } from "@jsenv/server/src/server_timing/timing_measure.js"
2
- import { composeTwoResponses } from "@jsenv/server/src/internal/response_composition.js"
3
- import { applyRedirectionToRequest } from "@jsenv/server/src/internal/request_factory.js"
1
+ import { timeFunction } from "../server_timing/timing_measure.js"
2
+ import { composeTwoResponses } from "../internal/response_composition.js"
3
+ import { applyRedirectionToRequest } from "../internal/request_factory.js"
4
4
 
5
5
  export const composeServices = (namedServices) => {
6
6
  return async (request, { pushResponse }) => {
@@ -6,6 +6,7 @@ import {
6
6
  raceProcessTeardownEvents,
7
7
  createCallbackListNotifiedOnce,
8
8
  } from "@jsenv/abort"
9
+ import { memoize } from "@jsenv/utils/src/memoize/memoize.js"
9
10
 
10
11
  import { createPolyglotServer } from "./internal/server-polyglot.js"
11
12
  import { trackServerPendingConnections } from "./internal/trackServerPendingConnections.js"
@@ -25,7 +26,6 @@ import { listen, stopListening } from "./internal/listen.js"
25
26
  import { composeTwoResponses } from "./internal/response_composition.js"
26
27
  import { listenRequest } from "./internal/listenRequest.js"
27
28
  import { listenServerConnectionError } from "./internal/listenServerConnectionError.js"
28
- import { memoize } from "./internal/memoize.js"
29
29
  import { applyDefaultErrorToResponse } from "./error_to_response_default.js"
30
30
  import {
31
31
  STOP_REASON_INTERNAL_ERROR,
@@ -804,7 +804,7 @@ const createNodeServer = async ({
804
804
  })
805
805
  }
806
806
 
807
- const { createServer } = await import("https")
807
+ const { createServer } = await import("node:https")
808
808
  return createServer({
809
809
  cert: certificate,
810
810
  key: privateKey,
@@ -1,24 +0,0 @@
1
- export const memoize = (compute) => {
2
- let memoized = false
3
- let memoizedValue
4
-
5
- const fnWithMemoization = (...args) => {
6
- if (memoized) {
7
- return memoizedValue
8
- }
9
- // if compute is recursive wait for it to be fully done before storing the value
10
- // so set memoized boolean after the call
11
- memoizedValue = compute(...args)
12
- memoized = true
13
- return memoizedValue
14
- }
15
-
16
- fnWithMemoization.forget = () => {
17
- const value = memoizedValue
18
- memoized = false
19
- memoizedValue = undefined
20
- return value
21
- }
22
-
23
- return fnWithMemoization
24
- }