@effect/platform-node 4.0.0-beta.7 → 4.0.0-beta.70
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/Mime.d.ts +3 -3
- package/dist/Mime.js +3 -3
- package/dist/NodeChildProcessSpawner.d.ts +1 -1
- package/dist/NodeChildProcessSpawner.js +1 -1
- package/dist/NodeClusterHttp.d.ts +49 -7
- package/dist/NodeClusterHttp.d.ts.map +1 -1
- package/dist/NodeClusterHttp.js +20 -10
- package/dist/NodeClusterHttp.js.map +1 -1
- package/dist/NodeClusterSocket.d.ts +57 -11
- package/dist/NodeClusterSocket.d.ts.map +1 -1
- package/dist/NodeClusterSocket.js +57 -11
- package/dist/NodeClusterSocket.js.map +1 -1
- package/dist/NodeCrypto.d.ts +10 -0
- package/dist/NodeCrypto.d.ts.map +1 -0
- package/dist/NodeCrypto.js +14 -0
- package/dist/NodeCrypto.js.map +1 -0
- package/dist/NodeFileSystem.d.ts +4 -2
- package/dist/NodeFileSystem.d.ts.map +1 -1
- package/dist/NodeFileSystem.js +22 -3
- package/dist/NodeFileSystem.js.map +1 -1
- package/dist/NodeHttpClient.d.ts +102 -24
- package/dist/NodeHttpClient.d.ts.map +1 -1
- package/dist/NodeHttpClient.js +124 -28
- package/dist/NodeHttpClient.js.map +1 -1
- package/dist/NodeHttpIncomingMessage.d.ts +30 -9
- package/dist/NodeHttpIncomingMessage.d.ts.map +1 -1
- package/dist/NodeHttpIncomingMessage.js +34 -8
- package/dist/NodeHttpIncomingMessage.js.map +1 -1
- package/dist/NodeHttpPlatform.d.ts +10 -4
- package/dist/NodeHttpPlatform.d.ts.map +1 -1
- package/dist/NodeHttpPlatform.js +34 -7
- package/dist/NodeHttpPlatform.js.map +1 -1
- package/dist/NodeHttpServer.d.ts +56 -16
- package/dist/NodeHttpServer.d.ts.map +1 -1
- package/dist/NodeHttpServer.js +117 -49
- package/dist/NodeHttpServer.js.map +1 -1
- package/dist/NodeHttpServerRequest.d.ts +29 -3
- package/dist/NodeHttpServerRequest.d.ts.map +1 -1
- package/dist/NodeHttpServerRequest.js +9 -2
- package/dist/NodeHttpServerRequest.js.map +1 -1
- package/dist/NodeMultipart.d.ts +32 -4
- package/dist/NodeMultipart.d.ts.map +1 -1
- package/dist/NodeMultipart.js +32 -4
- package/dist/NodeMultipart.js.map +1 -1
- package/dist/NodePath.d.ts +15 -6
- package/dist/NodePath.d.ts.map +1 -1
- package/dist/NodePath.js +30 -7
- package/dist/NodePath.js.map +1 -1
- package/dist/NodeRedis.d.ts +38 -9
- package/dist/NodeRedis.d.ts.map +1 -1
- package/dist/NodeRedis.js +41 -12
- package/dist/NodeRedis.js.map +1 -1
- package/dist/NodeRuntime.d.ts +27 -36
- package/dist/NodeRuntime.d.ts.map +1 -1
- package/dist/NodeRuntime.js +24 -13
- package/dist/NodeRuntime.js.map +1 -1
- package/dist/NodeServices.d.ts +29 -5
- package/dist/NodeServices.d.ts.map +1 -1
- package/dist/NodeServices.js +7 -3
- package/dist/NodeServices.js.map +1 -1
- package/dist/NodeSink.d.ts +2 -2
- package/dist/NodeSink.js +2 -2
- package/dist/NodeSocket.d.ts +18 -3
- package/dist/NodeSocket.d.ts.map +1 -1
- package/dist/NodeSocket.js +36 -4
- package/dist/NodeSocket.js.map +1 -1
- package/dist/NodeSocketServer.d.ts +2 -2
- package/dist/NodeSocketServer.js +2 -2
- package/dist/NodeStdio.d.ts +5 -2
- package/dist/NodeStdio.d.ts.map +1 -1
- package/dist/NodeStdio.js +22 -3
- package/dist/NodeStdio.js.map +1 -1
- package/dist/NodeStream.d.ts +2 -2
- package/dist/NodeStream.js +2 -2
- package/dist/NodeTerminal.d.ts +8 -2
- package/dist/NodeTerminal.d.ts.map +1 -1
- package/dist/NodeTerminal.js +19 -3
- package/dist/NodeTerminal.js.map +1 -1
- package/dist/NodeWorker.d.ts +9 -2
- package/dist/NodeWorker.d.ts.map +1 -1
- package/dist/NodeWorker.js +31 -6
- package/dist/NodeWorker.js.map +1 -1
- package/dist/NodeWorkerRunner.d.ts +5 -1
- package/dist/NodeWorkerRunner.d.ts.map +1 -1
- package/dist/NodeWorkerRunner.js +27 -5
- package/dist/NodeWorkerRunner.js.map +1 -1
- package/dist/Undici.d.ts +3 -3
- package/dist/Undici.js +3 -3
- package/dist/index.d.ts +376 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +376 -24
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/Mime.ts +3 -3
- package/src/NodeChildProcessSpawner.ts +1 -1
- package/src/NodeClusterHttp.ts +54 -11
- package/src/NodeClusterSocket.ts +57 -11
- package/src/NodeCrypto.ts +16 -0
- package/src/NodeFileSystem.ts +22 -3
- package/src/NodeHttpClient.ts +132 -33
- package/src/NodeHttpIncomingMessage.ts +42 -12
- package/src/NodeHttpPlatform.ts +35 -6
- package/src/NodeHttpServer.ts +139 -53
- package/src/NodeHttpServerRequest.ts +29 -3
- package/src/NodeMultipart.ts +32 -4
- package/src/NodePath.ts +30 -7
- package/src/NodeRedis.ts +43 -14
- package/src/NodeRuntime.ts +42 -37
- package/src/NodeServices.ts +31 -5
- package/src/NodeSink.ts +2 -2
- package/src/NodeSocket.ts +41 -4
- package/src/NodeSocketServer.ts +2 -2
- package/src/NodeStdio.ts +22 -3
- package/src/NodeStream.ts +2 -2
- package/src/NodeTerminal.ts +19 -3
- package/src/NodeWorker.ts +31 -6
- package/src/NodeWorkerRunner.ts +27 -5
- package/src/Undici.ts +3 -3
- package/src/index.ts +377 -24
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHttpIncomingMessage.d.ts","sourceRoot":"","sources":["../src/NodeHttpIncomingMessage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"NodeHttpIncomingMessage.d.ts","sourceRoot":"","sources":["../src/NodeHttpIncomingMessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAA;AACvD,OAAO,KAAK,eAAe,MAAM,0CAA0C,CAAA;AAC3E,OAAO,KAAK,SAAS,MAAM,gCAAgC,CAAA;AAC3D,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAA;AAGtC;;;;;;;GAOG;AACH,8BAAsB,uBAAuB,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,KACnE,YAAW,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAEjD;;;;OAIG;IACH,QAAQ,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,eAAe,CAAC,MAAM,CAAA;IAChE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAA;IACrC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAA;IACvC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;gBAGhE,MAAM,EAAE,IAAI,CAAC,eAAe,EAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,EAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAS/C,IAAI,OAAO,oBAEV;IAED,IAAI,aAAa,0BAEhB;IAED,OAAO,CAAC,UAAU,CAAsC;IACxD,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAgBnC;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAMxC;IAED,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAE5B;IAED,IAAI,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAMzD;IAED,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAKzC;IAED,OAAO,CAAC,iBAAiB,CAA2C;IACpE,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAe/C;CACF"}
|
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Utilities for adapting Node `http.IncomingMessage` values to the Effect HTTP
|
|
3
|
+
* incoming message interface used by the platform Node server and client
|
|
4
|
+
* implementations.
|
|
5
|
+
*
|
|
6
|
+
* This module is useful when code needs to keep access to Node's request or
|
|
7
|
+
* response object while also exposing Effect's typed headers, remote address,
|
|
8
|
+
* body decoders, and stream interface. The body helpers consume Node's readable
|
|
9
|
+
* stream, cache decoded text and array-buffer results, and honor the
|
|
10
|
+
* `HttpIncomingMessage.MaxBodySize` fiber ref. Prefer a single body access
|
|
11
|
+
* strategy per message: raw `stream` access is not cached, and Node request
|
|
12
|
+
* bodies cannot be replayed once the underlying stream has been consumed.
|
|
13
|
+
*
|
|
14
|
+
* @since 4.0.0
|
|
3
15
|
*/
|
|
4
16
|
import * as Effect from "effect/Effect";
|
|
5
17
|
import * as Inspectable from "effect/Inspectable";
|
|
18
|
+
import * as Option from "effect/Option";
|
|
6
19
|
import * as Headers from "effect/unstable/http/Headers";
|
|
7
20
|
import * as IncomingMessage from "effect/unstable/http/HttpIncomingMessage";
|
|
8
21
|
import * as UrlParams from "effect/unstable/http/UrlParams";
|
|
9
22
|
import * as NodeStream from "./NodeStream.js";
|
|
10
23
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
24
|
+
* Base adapter from Node `IncomingMessage` to Effect HTTP incoming messages,
|
|
25
|
+
* exposing headers, remote address, stream access, and cached text, JSON, URL
|
|
26
|
+
* parameter, and array-buffer body decoders with caller-provided error mapping.
|
|
27
|
+
*
|
|
28
|
+
* @category constructors
|
|
29
|
+
* @since 4.0.0
|
|
13
30
|
*/
|
|
14
31
|
export class NodeHttpIncomingMessage extends Inspectable.Class {
|
|
15
32
|
/**
|
|
16
|
-
*
|
|
33
|
+
* Marks this value as an HTTP incoming message for runtime guards.
|
|
34
|
+
*
|
|
35
|
+
* @since 4.0.0
|
|
17
36
|
*/
|
|
18
37
|
[IncomingMessage.TypeId];
|
|
19
38
|
source;
|
|
@@ -30,17 +49,18 @@ export class NodeHttpIncomingMessage extends Inspectable.Class {
|
|
|
30
49
|
return Headers.fromInput(this.source.headers);
|
|
31
50
|
}
|
|
32
51
|
get remoteAddress() {
|
|
33
|
-
return this.remoteAddressOverride ?? this.source.socket.remoteAddress;
|
|
52
|
+
return this.remoteAddressOverride ?? Option.fromNullishOr(this.source.socket.remoteAddress);
|
|
34
53
|
}
|
|
35
54
|
textEffect;
|
|
36
55
|
get text() {
|
|
37
56
|
if (this.textEffect) {
|
|
38
57
|
return this.textEffect;
|
|
39
58
|
}
|
|
40
|
-
this.textEffect = Effect.runSync(Effect.cached(Effect.flatMap(IncomingMessage.MaxBodySize
|
|
59
|
+
this.textEffect = Effect.runSync(Effect.cached(Effect.flatMap(IncomingMessage.MaxBodySize, maxBodySize => NodeStream.toString(() => this.source, {
|
|
41
60
|
onError: this.onError,
|
|
42
61
|
maxBytes: maxBodySize
|
|
43
62
|
}))));
|
|
63
|
+
this.arrayBufferEffect = Effect.map(this.textEffect, _ => new TextEncoder().encode(_).buffer);
|
|
44
64
|
return this.textEffect;
|
|
45
65
|
}
|
|
46
66
|
get textUnsafe() {
|
|
@@ -67,11 +87,17 @@ export class NodeHttpIncomingMessage extends Inspectable.Class {
|
|
|
67
87
|
onError: this.onError
|
|
68
88
|
});
|
|
69
89
|
}
|
|
90
|
+
arrayBufferEffect;
|
|
70
91
|
get arrayBuffer() {
|
|
71
|
-
|
|
92
|
+
if (this.arrayBufferEffect) {
|
|
93
|
+
return this.arrayBufferEffect;
|
|
94
|
+
}
|
|
95
|
+
this.arrayBufferEffect = Effect.withFiber(fiber => NodeStream.toArrayBuffer(() => this.source, {
|
|
72
96
|
onError: this.onError,
|
|
73
97
|
maxBytes: fiber.getRef(IncomingMessage.MaxBodySize)
|
|
74
|
-
}));
|
|
98
|
+
})).pipe(Effect.cached, Effect.runSync);
|
|
99
|
+
this.textEffect = Effect.map(this.arrayBufferEffect, _ => new TextDecoder().decode(_));
|
|
100
|
+
return this.arrayBufferEffect;
|
|
75
101
|
}
|
|
76
102
|
}
|
|
77
103
|
//# sourceMappingURL=NodeHttpIncomingMessage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHttpIncomingMessage.js","names":["Effect","Inspectable","Headers","IncomingMessage","UrlParams","NodeStream","NodeHttpIncomingMessage","Class","TypeId","source","onError","remoteAddressOverride","constructor","headers","fromInput","remoteAddress","socket","textEffect","text","runSync","cached","flatMap","MaxBodySize","
|
|
1
|
+
{"version":3,"file":"NodeHttpIncomingMessage.js","names":["Effect","Inspectable","Option","Headers","IncomingMessage","UrlParams","NodeStream","NodeHttpIncomingMessage","Class","TypeId","source","onError","remoteAddressOverride","constructor","headers","fromInput","remoteAddress","fromNullishOr","socket","textEffect","text","runSync","cached","flatMap","MaxBodySize","maxBodySize","toString","maxBytes","arrayBufferEffect","map","_","TextEncoder","encode","buffer","textUnsafe","json","try","JSON","parse","catch","jsonUnsafe","urlParamsBody","URLSearchParams","stream","fromReadable","evaluate","arrayBuffer","withFiber","fiber","toArrayBuffer","getRef","pipe","TextDecoder","decode"],"sources":["../src/NodeHttpIncomingMessage.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -3,8 +3,11 @@ import * as EtagImpl from "effect/unstable/http/Etag";
|
|
|
3
3
|
import * as Platform from "effect/unstable/http/HttpPlatform";
|
|
4
4
|
import * as ServerResponse from "effect/unstable/http/HttpServerResponse";
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Creates the Node `HttpPlatform`, serving file responses from Node readable
|
|
7
|
+
* streams and adding MIME type and content-length headers when needed.
|
|
8
|
+
*
|
|
9
|
+
* @category constructors
|
|
10
|
+
* @since 4.0.0
|
|
8
11
|
*/
|
|
9
12
|
export declare const make: import("effect/Effect").Effect<{
|
|
10
13
|
readonly fileResponse: (path: string, options?: ServerResponse.Options.WithContent & {
|
|
@@ -19,8 +22,11 @@ export declare const make: import("effect/Effect").Effect<{
|
|
|
19
22
|
}) => import("effect/Effect").Effect<ServerResponse.HttpServerResponse>;
|
|
20
23
|
}, never, import("effect/FileSystem").FileSystem | EtagImpl.Generator>;
|
|
21
24
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
25
|
+
* Provides the Node `HttpPlatform` together with the filesystem and ETag
|
|
26
|
+
* services it needs for file responses.
|
|
27
|
+
*
|
|
28
|
+
* @category layers
|
|
29
|
+
* @since 4.0.0
|
|
24
30
|
*/
|
|
25
31
|
export declare const layer: Layer.Layer<Platform.HttpPlatform>;
|
|
26
32
|
//# sourceMappingURL=NodeHttpPlatform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHttpPlatform.d.ts","sourceRoot":"","sources":["../src/NodeHttpPlatform.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NodeHttpPlatform.d.ts","sourceRoot":"","sources":["../src/NodeHttpPlatform.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,2BAA2B,CAAA;AAErD,OAAO,KAAK,QAAQ,MAAM,mCAAmC,CAAA;AAC7D,OAAO,KAAK,cAAc,MAAM,yCAAyC,CAAA;AAMzE;;;;;;GAMG;AACH,eAAO,MAAM,IAAI;iDAT+B,CAAC;4BAGI,CAAC;0BAChB,CAAC;uBAEhB,CAAC;;uGAKa,CAAA;4BAED,CAAA;0BAC7B,CAAC;uBAEE,CAAC;;sEAqBT,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAIpD,CAAA"}
|
package/dist/NodeHttpPlatform.js
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Node.js implementation of the Effect HTTP platform service.
|
|
3
|
+
*
|
|
4
|
+
* This module connects the portable `HttpPlatform` file response helpers to
|
|
5
|
+
* Node runtime primitives. It is used by Node HTTP servers and static file
|
|
6
|
+
* handlers when returning local files, public assets, downloads, byte ranges,
|
|
7
|
+
* or Web `File` values as `HttpServerResponse` bodies.
|
|
8
|
+
*
|
|
9
|
+
* Path-based responses are served with `node:fs.createReadStream`; Web `File`
|
|
10
|
+
* responses are bridged with `Readable.fromWeb`. The implementation fills in
|
|
11
|
+
* `content-type` from `Mime`, falls back to `application/octet-stream`, and
|
|
12
|
+
* writes the `content-length` for the selected range or whole file. Node's
|
|
13
|
+
* stream `end` option is inclusive, so the platform converts Effect's half-open
|
|
14
|
+
* range before reading. Empty bodies use an empty readable stream.
|
|
15
|
+
*
|
|
16
|
+
* Provide `layer` at the Node runtime edge when file responses, static serving,
|
|
17
|
+
* or response bodies created from files need real filesystem and ETag support.
|
|
18
|
+
* These responses are raw Node streams, so they are intended for the Node HTTP
|
|
19
|
+
* server adapter; keep files available until the response body has been
|
|
20
|
+
* consumed and prefer the portable `HttpServerResponse` constructors when a
|
|
21
|
+
* response does not depend on Node file or stream behavior.
|
|
22
|
+
*
|
|
23
|
+
* @since 4.0.0
|
|
3
24
|
*/
|
|
4
25
|
import { pipe } from "effect/Function";
|
|
5
26
|
import * as Layer from "effect/Layer";
|
|
@@ -12,14 +33,17 @@ import { Readable } from "node:stream";
|
|
|
12
33
|
import Mime from "./Mime.js";
|
|
13
34
|
import * as NodeFileSystem from "./NodeFileSystem.js";
|
|
14
35
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
36
|
+
* Creates the Node `HttpPlatform`, serving file responses from Node readable
|
|
37
|
+
* streams and adding MIME type and content-length headers when needed.
|
|
38
|
+
*
|
|
39
|
+
* @category constructors
|
|
40
|
+
* @since 4.0.0
|
|
17
41
|
*/
|
|
18
42
|
export const make = /*#__PURE__*/Platform.make({
|
|
19
43
|
fileResponse(path, status, statusText, headers, start, end, contentLength) {
|
|
20
|
-
const stream = Fs.createReadStream(path, {
|
|
44
|
+
const stream = contentLength === 0 ? Readable.from([]) : Fs.createReadStream(path, {
|
|
21
45
|
start,
|
|
22
|
-
end
|
|
46
|
+
end: end === undefined ? undefined : end - 1
|
|
23
47
|
});
|
|
24
48
|
return ServerResponse.raw(stream, {
|
|
25
49
|
headers: {
|
|
@@ -43,8 +67,11 @@ export const make = /*#__PURE__*/Platform.make({
|
|
|
43
67
|
}
|
|
44
68
|
});
|
|
45
69
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
70
|
+
* Provides the Node `HttpPlatform` together with the filesystem and ETag
|
|
71
|
+
* services it needs for file responses.
|
|
72
|
+
*
|
|
73
|
+
* @category layers
|
|
74
|
+
* @since 4.0.0
|
|
48
75
|
*/
|
|
49
76
|
export const layer = /*#__PURE__*/pipe(/*#__PURE__*/Layer.effect(Platform.HttpPlatform)(make), /*#__PURE__*/Layer.provide(NodeFileSystem.layer), /*#__PURE__*/Layer.provide(EtagImpl.layer));
|
|
50
77
|
//# sourceMappingURL=NodeHttpPlatform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHttpPlatform.js","names":["pipe","Layer","EtagImpl","Headers","Platform","ServerResponse","Fs","Readable","Mime","NodeFileSystem","make","fileResponse","path","status","statusText","headers","start","end","contentLength","stream","createReadStream","raw","getType","toString","fileWebResponse","file","_options","fromWeb","merge","fromRecordUnsafe","name","size","layer","effect","HttpPlatform","provide"],"sources":["../src/NodeHttpPlatform.ts"],"sourcesContent":[null],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"NodeHttpPlatform.js","names":["pipe","Layer","EtagImpl","Headers","Platform","ServerResponse","Fs","Readable","Mime","NodeFileSystem","make","fileResponse","path","status","statusText","headers","start","end","contentLength","stream","from","createReadStream","undefined","raw","getType","toString","fileWebResponse","file","_options","fromWeb","merge","fromRecordUnsafe","name","size","layer","effect","HttpPlatform","provide"],"sources":["../src/NodeHttpPlatform.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,QAAQ,MAAM,2BAA2B;AACrD,OAAO,KAAKC,OAAO,MAAM,8BAA8B;AACvD,OAAO,KAAKC,QAAQ,MAAM,mCAAmC;AAC7D,OAAO,KAAKC,cAAc,MAAM,yCAAyC;AACzE,OAAO,KAAKC,EAAE,MAAM,SAAS;AAC7B,SAASC,QAAQ,QAAQ,aAAa;AACtC,OAAOC,IAAI,MAAM,WAAW;AAC5B,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;;;;;AAOA,OAAO,MAAMC,IAAI,gBAAGN,QAAQ,CAACM,IAAI,CAAC;EAChCC,YAAYA,CAACC,IAAI,EAAEC,MAAM,EAAEC,UAAU,EAAEC,OAAO,EAAEC,KAAK,EAAEC,GAAG,EAAEC,aAAa;IACvE,MAAMC,MAAM,GAAGD,aAAa,KAAK,CAAC,GAC9BX,QAAQ,CAACa,IAAI,CAAC,EAAE,CAAC,GACjBd,EAAE,CAACe,gBAAgB,CAACT,IAAI,EAAE;MAAEI,KAAK;MAAEC,GAAG,EAAEA,GAAG,KAAKK,SAAS,GAAGA,SAAS,GAAGL,GAAG,GAAG;IAAC,CAAE,CAAC;IACtF,OAAOZ,cAAc,CAACkB,GAAG,CAACJ,MAAM,EAAE;MAChCJ,OAAO,EAAE;QACP,GAAGA,OAAO;QACV,cAAc,EAAEA,OAAO,CAAC,cAAc,CAAC,IAAIP,IAAI,CAACgB,OAAO,CAACZ,IAAI,CAAC,IAAI,0BAA0B;QAC3F,gBAAgB,EAAEM,aAAa,CAACO,QAAQ;OACzC;MACDZ,MAAM;MACNC;KACD,CAAC;EACJ,CAAC;EACDY,eAAeA,CAACC,IAAI,EAAEd,MAAM,EAAEC,UAAU,EAAEC,OAAO,EAAEa,QAAQ;IACzD,OAAOvB,cAAc,CAACkB,GAAG,CAAChB,QAAQ,CAACsB,OAAO,CAACF,IAAI,CAACR,MAAM,EAAS,CAAC,EAAE;MAChEJ,OAAO,EAAEZ,OAAO,CAAC2B,KAAK,CACpBf,OAAO,EACPZ,OAAO,CAAC4B,gBAAgB,CAAC;QACvB,cAAc,EAAEhB,OAAO,CAAC,cAAc,CAAC,IAAIP,IAAI,CAACgB,OAAO,CAACG,IAAI,CAACK,IAAI,CAAC,IAAI,0BAA0B;QAChG,gBAAgB,EAAEL,IAAI,CAACM,IAAI,CAACR,QAAQ;OACrC,CAAC,CACH;MACDZ,MAAM;MACNC;KACD,CAAC;EACJ;CACD,CAAC;AAEF;;;;;;;AAOA,OAAO,MAAMoB,KAAK,gBAAuClC,IAAI,cAC3DC,KAAK,CAACkC,MAAM,CAAC/B,QAAQ,CAACgC,YAAY,CAAC,CAAC1B,IAAI,CAAC,eACzCT,KAAK,CAACoC,OAAO,CAAC5B,cAAc,CAACyB,KAAK,CAAC,eACnCjC,KAAK,CAACoC,OAAO,CAACnC,QAAQ,CAACgC,KAAK,CAAC,CAC9B","ignoreList":[]}
|
package/dist/NodeHttpServer.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Config from "effect/Config";
|
|
2
|
+
import * as Duration from "effect/Duration";
|
|
2
3
|
import * as Effect from "effect/Effect";
|
|
3
4
|
import type * as FileSystem from "effect/FileSystem";
|
|
4
5
|
import { type LazyArg } from "effect/Function";
|
|
@@ -19,10 +20,17 @@ import type { Duplex } from "node:stream";
|
|
|
19
20
|
import * as NodeServices from "./NodeServices.ts";
|
|
20
21
|
import { NodeWS } from "./NodeSocket.ts";
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
+
* Creates a scoped `HttpServer` from a Node `http.Server`, starts listening
|
|
24
|
+
* with the supplied options, registers request and upgrade handling, and closes
|
|
25
|
+
* the server during scope finalization with optional graceful-shutdown control.
|
|
26
|
+
*
|
|
23
27
|
* @category constructors
|
|
28
|
+
* @since 4.0.0
|
|
24
29
|
*/
|
|
25
|
-
export declare const make: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Net.ListenOptions
|
|
30
|
+
export declare const make: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Net.ListenOptions & {
|
|
31
|
+
readonly disablePreemptiveShutdown?: boolean | undefined;
|
|
32
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined;
|
|
33
|
+
}) => Effect.Effect<{
|
|
26
34
|
readonly serve: {
|
|
27
35
|
<E, R>(effect: Effect.Effect<HttpServerResponse, E, R>): Effect.Effect<void, never, Exclude<R, HttpServerRequest> | Scope.Scope>;
|
|
28
36
|
<E, R, App extends Effect.Effect<HttpServerResponse, any, any>>(effect: Effect.Effect<HttpServerResponse, E, R>, middleware: Middleware.HttpMiddleware.Applied<App, E, R>): Effect.Effect<void, never, Exclude<R, HttpServerRequest> | Scope.Scope>;
|
|
@@ -30,44 +38,76 @@ export declare const make: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMe
|
|
|
30
38
|
readonly address: HttpServer.Address;
|
|
31
39
|
}, ServeError, Scope.Scope>;
|
|
32
40
|
/**
|
|
33
|
-
*
|
|
41
|
+
* Creates a Node `request` event handler for an Effect HTTP application,
|
|
42
|
+
* injecting a `HttpServerRequest` and interrupting the request fiber if the
|
|
43
|
+
* client closes the response before it finishes.
|
|
44
|
+
*
|
|
34
45
|
* @category Handlers
|
|
46
|
+
* @since 4.0.0
|
|
35
47
|
*/
|
|
36
48
|
export declare const makeHandler: <R, E, App extends Effect.Effect<HttpServerResponse, any, any> = Effect.Effect<HttpServerResponse, E, R>>(httpEffect: Effect.Effect<HttpServerResponse, E, R>, options: {
|
|
37
49
|
readonly scope: Scope.Scope;
|
|
38
50
|
readonly middleware?: Middleware.HttpMiddleware.Applied<App, E, R> | undefined;
|
|
39
51
|
}) => Effect.Effect<(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse) => void, never, Exclude<Effect.Services<App>, HttpServerRequest | Scope.Scope>>;
|
|
40
52
|
/**
|
|
41
|
-
*
|
|
53
|
+
* Creates a Node `upgrade` event handler for an Effect HTTP application,
|
|
54
|
+
* exposing the upgraded WebSocket as the request's `upgrade` effect and
|
|
55
|
+
* interrupting the request fiber when the socket closes early.
|
|
56
|
+
*
|
|
42
57
|
* @category Handlers
|
|
58
|
+
* @since 4.0.0
|
|
43
59
|
*/
|
|
44
60
|
export declare const makeUpgradeHandler: <R, E, App extends Effect.Effect<HttpServerResponse, any, any> = Effect.Effect<HttpServerResponse, E, R>>(lazyWss: Effect.Effect<NodeWS.WebSocketServer>, httpEffect: Effect.Effect<HttpServerResponse, E, R>, options: {
|
|
45
61
|
readonly scope: Scope.Scope;
|
|
46
62
|
readonly middleware?: Middleware.HttpMiddleware.Applied<App, E, R> | undefined;
|
|
47
63
|
}) => Effect.Effect<(nodeRequest: Http.IncomingMessage, socket: Duplex, head: Buffer) => void, never, Exclude<Effect.Services<App>, HttpServerRequest | Scope.Scope>>;
|
|
48
64
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
65
|
+
* Provides an `HttpServer` by creating and managing a scoped Node
|
|
66
|
+
* `http.Server` with the supplied listen and shutdown options.
|
|
67
|
+
*
|
|
68
|
+
* @category layers
|
|
69
|
+
* @since 4.0.0
|
|
51
70
|
*/
|
|
52
|
-
export declare const layerServer: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Net.ListenOptions
|
|
71
|
+
export declare const layerServer: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Net.ListenOptions & {
|
|
72
|
+
readonly disablePreemptiveShutdown?: boolean | undefined;
|
|
73
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined;
|
|
74
|
+
}) => Layer.Layer<HttpServer.HttpServer, ServeError>;
|
|
53
75
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
76
|
+
* Provides the Node HTTP support services used by `NodeHttpServer`, including
|
|
77
|
+
* the HTTP platform, ETag generator, and core Node platform services.
|
|
78
|
+
*
|
|
79
|
+
* @category layers
|
|
80
|
+
* @since 4.0.0
|
|
56
81
|
*/
|
|
57
82
|
export declare const layerHttpServices: Layer.Layer<NodeServices.NodeServices | HttpPlatform.HttpPlatform | Etag.Generator>;
|
|
58
83
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
84
|
+
* Provides a Node `HttpServer` together with the Node HTTP platform, ETag, and
|
|
85
|
+
* core platform services required to serve requests.
|
|
86
|
+
*
|
|
87
|
+
* @category layers
|
|
88
|
+
* @since 4.0.0
|
|
61
89
|
*/
|
|
62
|
-
export declare const layer: (evaluate: LazyArg<Http.Server>, options: Net.ListenOptions
|
|
90
|
+
export declare const layer: (evaluate: LazyArg<Http.Server>, options: Net.ListenOptions & {
|
|
91
|
+
readonly disablePreemptiveShutdown?: boolean | undefined;
|
|
92
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined;
|
|
93
|
+
}) => Layer.Layer<HttpServer.HttpServer | NodeServices.NodeServices | HttpPlatform.HttpPlatform | Etag.Generator, ServeError>;
|
|
63
94
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
95
|
+
* Provides a Node `HttpServer` and HTTP support services, reading the listen
|
|
96
|
+
* and shutdown options from a `Config` value.
|
|
97
|
+
*
|
|
98
|
+
* @category layers
|
|
99
|
+
* @since 4.0.0
|
|
66
100
|
*/
|
|
67
|
-
export declare const layerConfig: (evaluate: LazyArg<Http.Server>, options: Config.Wrap<Net.ListenOptions
|
|
101
|
+
export declare const layerConfig: (evaluate: LazyArg<Http.Server>, options: Config.Wrap<Net.ListenOptions & {
|
|
102
|
+
readonly disablePreemptiveShutdown?: boolean | undefined;
|
|
103
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined;
|
|
104
|
+
}>) => Layer.Layer<HttpServer.HttpServer | FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform | Etag.Generator, ServeError | Config.ConfigError>;
|
|
68
105
|
/**
|
|
69
|
-
*
|
|
106
|
+
* Provides a test HTTP server listening on an ephemeral port together with a
|
|
107
|
+
* Fetch-backed `HttpClient` configured for server integration tests.
|
|
108
|
+
*
|
|
70
109
|
* @category Testing
|
|
110
|
+
* @since 4.0.0
|
|
71
111
|
*/
|
|
72
112
|
export declare const layerTest: Layer.Layer<HttpServer.HttpServer | FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform | Etag.Generator | HttpClient, ServeError, never>;
|
|
73
113
|
//# sourceMappingURL=NodeHttpServer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHttpServer.d.ts","sourceRoot":"","sources":["../src/NodeHttpServer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NodeHttpServer.d.ts","sourceRoot":"","sources":["../src/NodeHttpServer.ts"],"names":[],"mappings":"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"}
|
package/dist/NodeHttpServer.js
CHANGED
|
@@ -1,15 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Node.js implementation of the Effect `HttpServer`.
|
|
3
|
+
*
|
|
4
|
+
* This module adapts a supplied Node `http.Server` into Effect's
|
|
5
|
+
* platform-independent HTTP server service. It starts the server with Node
|
|
6
|
+
* `listen` options, converts `request` events into `HttpServerRequest` values,
|
|
7
|
+
* writes `HttpServerResponse` bodies through Node's `ServerResponse`, and
|
|
8
|
+
* handles `upgrade` events by exposing the upgraded socket through
|
|
9
|
+
* `HttpServerRequest.upgrade`.
|
|
10
|
+
*
|
|
11
|
+
* Common use cases include serving an Effect HTTP application with {@link layer}
|
|
12
|
+
* or {@link layerConfig}, embedding request or upgrade handlers into an
|
|
13
|
+
* existing Node server with {@link makeHandler} and {@link makeUpgradeHandler},
|
|
14
|
+
* and using {@link layerTest} for integration tests that need an ephemeral
|
|
15
|
+
* listening port and a client pointed at it.
|
|
16
|
+
*
|
|
17
|
+
* Listen options are passed directly to Node, so host, port, backlog, and Unix
|
|
18
|
+
* socket path behavior follow `node:http`. The server begins listening when the
|
|
19
|
+
* `HttpServer` is acquired, and handlers are installed when `serve` is run.
|
|
20
|
+
* Request fibers are interrupted with `ClientAbort` when the client disconnects
|
|
21
|
+
* before a response finishes. WebSocket support only applies to Node `upgrade`
|
|
22
|
+
* requests, and ordinary HTTP requests fail if their application attempts to use
|
|
23
|
+
* `HttpServerRequest.upgrade`.
|
|
24
|
+
*
|
|
25
|
+
* Scope ownership is important: the server is closed when the acquiring scope
|
|
26
|
+
* finalizes, while each `serve` call installs its own request and upgrade
|
|
27
|
+
* listeners and removes them on finalization. Unless preemptive shutdown is
|
|
28
|
+
* disabled, finalizing a serve scope also starts a graceful server close, using
|
|
29
|
+
* the configured timeout or the default timeout.
|
|
30
|
+
*
|
|
31
|
+
* @since 4.0.0
|
|
3
32
|
*/
|
|
4
33
|
import * as Cause from "effect/Cause";
|
|
5
34
|
import * as Config from "effect/Config";
|
|
35
|
+
import * as Context from "effect/Context";
|
|
36
|
+
import * as Duration from "effect/Duration";
|
|
6
37
|
import * as Effect from "effect/Effect";
|
|
7
38
|
import * as Fiber from "effect/Fiber";
|
|
8
39
|
import { flow } from "effect/Function";
|
|
9
40
|
import * as Latch from "effect/Latch";
|
|
10
41
|
import * as Layer from "effect/Layer";
|
|
11
42
|
import * as Scope from "effect/Scope";
|
|
12
|
-
import * as ServiceMap from "effect/ServiceMap";
|
|
13
43
|
import * as Stream from "effect/Stream";
|
|
14
44
|
import * as Cookies from "effect/unstable/http/Cookies";
|
|
15
45
|
import * as Etag from "effect/unstable/http/Etag";
|
|
@@ -17,7 +47,7 @@ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
|
17
47
|
import * as HttpEffect from "effect/unstable/http/HttpEffect";
|
|
18
48
|
import * as HttpIncomingMessage from "effect/unstable/http/HttpIncomingMessage";
|
|
19
49
|
import * as HttpServer from "effect/unstable/http/HttpServer";
|
|
20
|
-
import { causeResponse,
|
|
50
|
+
import { causeResponse, ClientAbort, HttpServerError, RequestParseError, ResponseError, ServeError } from "effect/unstable/http/HttpServerError";
|
|
21
51
|
import * as Request from "effect/unstable/http/HttpServerRequest";
|
|
22
52
|
import { HttpServerRequest } from "effect/unstable/http/HttpServerRequest";
|
|
23
53
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
@@ -30,13 +60,17 @@ import * as NodeMultipart from "./NodeMultipart.js";
|
|
|
30
60
|
import * as NodeServices from "./NodeServices.js";
|
|
31
61
|
import { NodeWS } from "./NodeSocket.js";
|
|
32
62
|
/**
|
|
33
|
-
*
|
|
63
|
+
* Creates a scoped `HttpServer` from a Node `http.Server`, starts listening
|
|
64
|
+
* with the supplied options, registers request and upgrade handling, and closes
|
|
65
|
+
* the server during scope finalization with optional graceful-shutdown control.
|
|
66
|
+
*
|
|
34
67
|
* @category constructors
|
|
68
|
+
* @since 4.0.0
|
|
35
69
|
*/
|
|
36
70
|
export const make = /*#__PURE__*/Effect.fnUntraced(function* (evaluate, options) {
|
|
37
71
|
const scope = yield* Effect.scope;
|
|
38
72
|
const server = evaluate();
|
|
39
|
-
yield*
|
|
73
|
+
const shutdown = yield* Effect.callback(resume => {
|
|
40
74
|
if (!server.listening) {
|
|
41
75
|
return resume(Effect.void);
|
|
42
76
|
}
|
|
@@ -47,7 +81,12 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* (evaluate, options)
|
|
|
47
81
|
resume(Effect.void);
|
|
48
82
|
}
|
|
49
83
|
});
|
|
50
|
-
}));
|
|
84
|
+
}).pipe(Effect.cached);
|
|
85
|
+
const preemptiveShutdown = options.disablePreemptiveShutdown ? Effect.void : Effect.timeoutOrElse(shutdown, {
|
|
86
|
+
duration: options.gracefulShutdownTimeout ?? Duration.seconds(20),
|
|
87
|
+
orElse: () => Effect.void
|
|
88
|
+
});
|
|
89
|
+
yield* Scope.addFinalizer(scope, shutdown);
|
|
51
90
|
yield* Effect.callback(resume => {
|
|
52
91
|
function onError(cause) {
|
|
53
92
|
resume(Effect.fail(new ServeError({
|
|
@@ -76,7 +115,8 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* (evaluate, options)
|
|
|
76
115
|
port: address.port
|
|
77
116
|
},
|
|
78
117
|
serve: Effect.fnUntraced(function* (httpApp, middleware) {
|
|
79
|
-
const
|
|
118
|
+
const serveScope = yield* Effect.scope;
|
|
119
|
+
const scope = Scope.forkUnsafe(serveScope, "parallel");
|
|
80
120
|
const handler = yield* makeHandler(httpApp, {
|
|
81
121
|
middleware: middleware,
|
|
82
122
|
scope
|
|
@@ -85,62 +125,75 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* (evaluate, options)
|
|
|
85
125
|
middleware: middleware,
|
|
86
126
|
scope
|
|
87
127
|
});
|
|
88
|
-
yield*
|
|
128
|
+
yield* Scope.addFinalizerExit(serveScope, () => {
|
|
89
129
|
server.off("request", handler);
|
|
90
130
|
server.off("upgrade", upgradeHandler);
|
|
91
|
-
|
|
131
|
+
return preemptiveShutdown;
|
|
132
|
+
});
|
|
92
133
|
server.on("request", handler);
|
|
93
134
|
server.on("upgrade", upgradeHandler);
|
|
94
135
|
})
|
|
95
136
|
});
|
|
96
137
|
});
|
|
97
138
|
/**
|
|
98
|
-
*
|
|
139
|
+
* Creates a Node `request` event handler for an Effect HTTP application,
|
|
140
|
+
* injecting a `HttpServerRequest` and interrupting the request fiber if the
|
|
141
|
+
* client closes the response before it finishes.
|
|
142
|
+
*
|
|
99
143
|
* @category Handlers
|
|
144
|
+
* @since 4.0.0
|
|
100
145
|
*/
|
|
101
146
|
export const makeHandler = (httpEffect, options) => {
|
|
102
147
|
const handled = HttpEffect.toHandled(httpEffect, handleResponse, options.middleware);
|
|
103
|
-
return Effect.
|
|
104
|
-
|
|
148
|
+
return Effect.withFiber(parent => {
|
|
149
|
+
const services = parent.context;
|
|
150
|
+
return Effect.succeed(function handler(nodeRequest, nodeResponse) {
|
|
105
151
|
const map = new Map(services.mapUnsafe);
|
|
106
152
|
map.set(HttpServerRequest.key, new ServerRequestImpl(nodeRequest, nodeResponse));
|
|
107
|
-
const fiber = Fiber.runIn(Effect.runForkWith(
|
|
153
|
+
const fiber = Fiber.runIn(Effect.runForkWith(Context.makeUnsafe(map))(handled), options.scope);
|
|
108
154
|
nodeResponse.on("close", () => {
|
|
109
155
|
if (!nodeResponse.writableEnded) {
|
|
110
|
-
fiber.interruptUnsafe(
|
|
156
|
+
fiber.interruptUnsafe(parent.id, ClientAbort.annotation);
|
|
111
157
|
}
|
|
112
158
|
});
|
|
113
|
-
};
|
|
159
|
+
});
|
|
114
160
|
});
|
|
115
161
|
};
|
|
116
162
|
/**
|
|
117
|
-
*
|
|
163
|
+
* Creates a Node `upgrade` event handler for an Effect HTTP application,
|
|
164
|
+
* exposing the upgraded WebSocket as the request's `upgrade` effect and
|
|
165
|
+
* interrupting the request fiber when the socket closes early.
|
|
166
|
+
*
|
|
118
167
|
* @category Handlers
|
|
168
|
+
* @since 4.0.0
|
|
119
169
|
*/
|
|
120
170
|
export const makeUpgradeHandler = (lazyWss, httpEffect, options) => {
|
|
121
171
|
const handledApp = HttpEffect.toHandled(httpEffect, handleResponse, options.middleware);
|
|
122
|
-
return Effect.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
nodeResponse_
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
172
|
+
return Effect.withFiber(parent => {
|
|
173
|
+
const services = parent.context;
|
|
174
|
+
return Effect.succeed(function handler(nodeRequest, socket, head) {
|
|
175
|
+
let nodeResponse_ = undefined;
|
|
176
|
+
const nodeResponse = () => {
|
|
177
|
+
if (nodeResponse_ === undefined) {
|
|
178
|
+
nodeResponse_ = new Http.ServerResponse(nodeRequest);
|
|
179
|
+
nodeResponse_.assignSocket(socket);
|
|
180
|
+
nodeResponse_.on("finish", () => {
|
|
181
|
+
socket.end();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return nodeResponse_;
|
|
185
|
+
};
|
|
186
|
+
const upgradeEffect = Socket.fromWebSocket(Effect.flatMap(lazyWss, wss => Effect.acquireRelease(Effect.callback(resume => wss.handleUpgrade(nodeRequest, socket, head, ws => {
|
|
187
|
+
resume(Effect.succeed(ws));
|
|
188
|
+
})), ws => Effect.sync(() => ws.close()))));
|
|
189
|
+
const map = new Map(services.mapUnsafe);
|
|
190
|
+
map.set(HttpServerRequest.key, new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect));
|
|
191
|
+
const fiber = Fiber.runIn(Effect.runForkWith(Context.makeUnsafe(map))(handledApp), options.scope);
|
|
192
|
+
socket.on("close", () => {
|
|
193
|
+
if (!socket.writableEnded) {
|
|
194
|
+
fiber.interruptUnsafe(parent.id, ClientAbort.annotation);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
144
197
|
});
|
|
145
198
|
});
|
|
146
199
|
};
|
|
@@ -174,7 +227,7 @@ class ServerRequestImpl extends NodeHttpIncomingMessage {
|
|
|
174
227
|
return typeof this.response === "function" ? this.response() : this.response;
|
|
175
228
|
}
|
|
176
229
|
modify(options) {
|
|
177
|
-
return new ServerRequestImpl(this.source, this.response, this.upgradeEffect, options.url ?? this.url, options.headers ?? this.headersOverride, options.remoteAddress
|
|
230
|
+
return new ServerRequestImpl(this.source, this.response, this.upgradeEffect, options.url ?? this.url, options.headers ?? this.headersOverride, "remoteAddress" in options ? options.remoteAddress : this.remoteAddressOverride);
|
|
178
231
|
}
|
|
179
232
|
get originalUrl() {
|
|
180
233
|
return this.source.url;
|
|
@@ -217,28 +270,43 @@ class ServerRequestImpl extends NodeHttpIncomingMessage {
|
|
|
217
270
|
}
|
|
218
271
|
}
|
|
219
272
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
273
|
+
* Provides an `HttpServer` by creating and managing a scoped Node
|
|
274
|
+
* `http.Server` with the supplied listen and shutdown options.
|
|
275
|
+
*
|
|
276
|
+
* @category layers
|
|
277
|
+
* @since 4.0.0
|
|
222
278
|
*/
|
|
223
279
|
export const layerServer = /*#__PURE__*/flow(make, /*#__PURE__*/Layer.effect(HttpServer.HttpServer));
|
|
224
280
|
/**
|
|
225
|
-
*
|
|
226
|
-
*
|
|
281
|
+
* Provides the Node HTTP support services used by `NodeHttpServer`, including
|
|
282
|
+
* the HTTP platform, ETag generator, and core Node platform services.
|
|
283
|
+
*
|
|
284
|
+
* @category layers
|
|
285
|
+
* @since 4.0.0
|
|
227
286
|
*/
|
|
228
287
|
export const layerHttpServices = /*#__PURE__*/Layer.mergeAll(NodeHttpPlatform.layer, Etag.layerWeak, NodeServices.layer);
|
|
229
288
|
/**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
289
|
+
* Provides a Node `HttpServer` together with the Node HTTP platform, ETag, and
|
|
290
|
+
* core platform services required to serve requests.
|
|
291
|
+
*
|
|
292
|
+
* @category layers
|
|
293
|
+
* @since 4.0.0
|
|
232
294
|
*/
|
|
233
295
|
export const layer = (evaluate, options) => Layer.mergeAll(layerServer(evaluate, options), layerHttpServices);
|
|
234
296
|
/**
|
|
235
|
-
*
|
|
236
|
-
*
|
|
297
|
+
* Provides a Node `HttpServer` and HTTP support services, reading the listen
|
|
298
|
+
* and shutdown options from a `Config` value.
|
|
299
|
+
*
|
|
300
|
+
* @category layers
|
|
301
|
+
* @since 4.0.0
|
|
237
302
|
*/
|
|
238
|
-
export const layerConfig = (evaluate, options) => Layer.mergeAll(Layer.effect(HttpServer.HttpServer)(Effect.flatMap(Config.unwrap(options)
|
|
303
|
+
export const layerConfig = (evaluate, options) => Layer.mergeAll(Layer.effect(HttpServer.HttpServer)(Effect.flatMap(Config.unwrap(options), options => make(evaluate, options))), layerHttpServices);
|
|
239
304
|
/**
|
|
240
|
-
*
|
|
305
|
+
* Provides a test HTTP server listening on an ephemeral port together with a
|
|
306
|
+
* Fetch-backed `HttpClient` configured for server integration tests.
|
|
307
|
+
*
|
|
241
308
|
* @category Testing
|
|
309
|
+
* @since 4.0.0
|
|
242
310
|
*/
|
|
243
311
|
export const layerTest = /*#__PURE__*/HttpServer.layerTestClient.pipe(/*#__PURE__*/Layer.provide(/*#__PURE__*/Layer.fresh(FetchHttpClient.layer).pipe(/*#__PURE__*/Layer.provide(/*#__PURE__*/Layer.succeed(FetchHttpClient.RequestInit)({
|
|
244
312
|
keepalive: false
|