@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.
|
|
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.
|
|
39
|
-
"@jsenv/
|
|
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/",
|
package/src/fetch_filesystem.js
CHANGED
|
@@ -4,23 +4,17 @@
|
|
|
4
4
|
* It is meant to be used inside "requestToResponse"
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createReadStream, statSync,
|
|
8
|
-
import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
302
|
-
|
|
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(
|
|
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 "
|
|
2
|
-
import { composeTwoResponses } from "
|
|
3
|
-
import { applyRedirectionToRequest } from "
|
|
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 }) => {
|
package/src/startServer.js
CHANGED
|
@@ -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,
|
package/src/internal/memoize.js
DELETED
|
@@ -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
|
-
}
|