@effect/platform-node 4.0.0-beta.102 → 4.0.0-beta.103
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.js.map +1 -1
- package/dist/NodeClusterHttp.d.ts +1 -0
- package/dist/NodeClusterHttp.d.ts.map +1 -1
- package/dist/NodeClusterHttp.js +5 -1
- package/dist/NodeClusterHttp.js.map +1 -1
- package/dist/NodeClusterSocket.d.ts +1 -0
- package/dist/NodeClusterSocket.d.ts.map +1 -1
- package/dist/NodeClusterSocket.js +9 -2
- package/dist/NodeClusterSocket.js.map +1 -1
- package/dist/NodeCrypto.js.map +1 -1
- package/dist/NodeFileSystem.js.map +1 -1
- package/dist/NodeHttpClient.d.ts +18 -18
- package/dist/NodeHttpClient.d.ts.map +1 -1
- package/dist/NodeHttpClient.js +25 -19
- package/dist/NodeHttpClient.js.map +1 -1
- package/dist/NodeHttpIncomingMessage.js.map +1 -1
- package/dist/NodeHttpPlatform.d.ts +8 -4
- package/dist/NodeHttpPlatform.d.ts.map +1 -1
- package/dist/NodeHttpPlatform.js +38 -0
- package/dist/NodeHttpPlatform.js.map +1 -1
- package/dist/NodeHttpServer.d.ts +21 -16
- package/dist/NodeHttpServer.d.ts.map +1 -1
- package/dist/NodeHttpServer.js +22 -20
- package/dist/NodeHttpServer.js.map +1 -1
- package/dist/NodeHttpServerRequest.js.map +1 -1
- package/dist/NodeMultipart.js.map +1 -1
- package/dist/NodePath.js.map +1 -1
- package/dist/NodeRedis.js.map +1 -1
- package/dist/NodeRuntime.js.map +1 -1
- package/dist/NodeServices.js.map +1 -1
- package/dist/NodeSocket.js.map +1 -1
- package/dist/NodeStdio.js.map +1 -1
- package/dist/NodeTerminal.js.map +1 -1
- package/dist/NodeWorker.js.map +1 -1
- package/dist/NodeWorkerRunner.d.ts.map +1 -1
- package/dist/NodeWorkerRunner.js +30 -18
- package/dist/NodeWorkerRunner.js.map +1 -1
- package/dist/Undici.d.ts +2 -2
- package/dist/Undici.js +2 -2
- package/dist/Undici.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -11
- package/src/NodeClusterHttp.ts +4 -1
- package/src/NodeClusterSocket.ts +6 -1
- package/src/NodeHttpClient.ts +22 -18
- package/src/NodeHttpPlatform.ts +49 -0
- package/src/NodeHttpServer.ts +60 -45
- package/src/NodeWorkerRunner.ts +39 -23
- package/src/Undici.ts +2 -2
package/dist/Undici.js
CHANGED
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import Undici from "undici";
|
|
18
18
|
/**
|
|
19
|
-
* @category
|
|
19
|
+
* @category re-exports
|
|
20
20
|
* @since 4.0.0
|
|
21
21
|
*/
|
|
22
22
|
export * from "undici";
|
|
23
23
|
/**
|
|
24
|
-
* @category
|
|
24
|
+
* @category re-exports
|
|
25
25
|
* @since 4.0.0
|
|
26
26
|
*/
|
|
27
27
|
export default Undici;
|
package/dist/Undici.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Undici.js","names":[
|
|
1
|
+
{"version":3,"file":"Undici.js","names":[],"sources":["../src/Undici.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;AAgBA,OAAO,MAAM,MAAM,QAAQ;AAE3B;;;;AAIA,cAAc,QAAQ;AAEtB;;;;AAIA,eAAe,MAAM","ignoreList":[]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAIA;AAEA;;;AAGA,OAAO,KAAK,IAAI,MAAM,WAAW;AAEjC;;;AAGA,OAAO,KAAK,uBAAuB,MAAM,8BAA8B;AAEvE;;;AAGA,OAAO,KAAK,eAAe,MAAM,sBAAsB;AAEvD;;;AAGA,OAAO,KAAK,iBAAiB,MAAM,wBAAwB;AAE3D;;;AAGA,OAAO,KAAK,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAK,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAK,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAK,uBAAuB,MAAM,8BAA8B;AAEvE;;;AAGA,OAAO,KAAK,gBAAgB,MAAM,uBAAuB;AAEzD;;;AAGA,OAAO,KAAK,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAK,qBAAqB,MAAM,4BAA4B;AAEnE;;;AAGA,OAAO,KAAK,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAK,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAK,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAK,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAK,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAK,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAK,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAK,gBAAgB,MAAM,uBAAuB;AAEzD;;;AAGA,OAAO,KAAK,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAK,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAK,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAK,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAK,gBAAgB,MAAM,uBAAuB;AAEzD;;;AAGA,OAAO,KAAK,MAAM,MAAM,aAAa","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/platform-node",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.103",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Platform specific implementations for the Node.js runtime",
|
|
7
7
|
"homepage": "https://effect.website",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
".": "./dist/index.js",
|
|
35
35
|
"./*": "./dist/*.js",
|
|
36
36
|
"./internal/*": null,
|
|
37
|
+
"./index": null,
|
|
37
38
|
"./*/index": null
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
@@ -50,25 +51,23 @@
|
|
|
50
51
|
"dependencies": {
|
|
51
52
|
"mime": "^4.1.0",
|
|
52
53
|
"undici": "^8.7.0",
|
|
53
|
-
"@effect/platform-node-shared": "^4.0.0-beta.
|
|
54
|
+
"@effect/platform-node-shared": "^4.0.0-beta.103"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"ioredis": "^5.7.0",
|
|
57
|
-
"effect": "^4.0.0-beta.
|
|
58
|
+
"effect": "^4.0.0-beta.103"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"@testcontainers/mysql": "^
|
|
61
|
-
"@testcontainers/postgresql": "^
|
|
62
|
-
"@testcontainers/redis": "^
|
|
63
|
-
"@types/node": "^26.1.
|
|
64
|
-
"effect": "^4.0.0-beta.
|
|
61
|
+
"@testcontainers/mysql": "^12.0.4",
|
|
62
|
+
"@testcontainers/postgresql": "^12.0.4",
|
|
63
|
+
"@testcontainers/redis": "^12.0.4",
|
|
64
|
+
"@types/node": "^26.1.2",
|
|
65
|
+
"effect": "^4.0.0-beta.103"
|
|
65
66
|
},
|
|
66
67
|
"scripts": {
|
|
67
68
|
"codegen": "effect-utils codegen",
|
|
68
69
|
"build": "tsc -b tsconfig.json && pnpm babel",
|
|
69
70
|
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
|
70
|
-
"check": "tsc -b tsconfig.json"
|
|
71
|
-
"test": "vitest",
|
|
72
|
-
"coverage": "vitest --coverage"
|
|
71
|
+
"check": "tsc -b tsconfig.json"
|
|
73
72
|
}
|
|
74
73
|
}
|
package/src/NodeClusterHttp.ts
CHANGED
|
@@ -61,6 +61,7 @@ export const layer = <
|
|
|
61
61
|
>(options: {
|
|
62
62
|
readonly transport: "http" | "websocket"
|
|
63
63
|
readonly serialization?: "msgpack" | "ndjson" | undefined
|
|
64
|
+
readonly serializationMaxBufferSize?: number | "unbounded" | undefined
|
|
64
65
|
readonly clientOnly?: ClientOnly | undefined
|
|
65
66
|
readonly storage?: Storage | undefined
|
|
66
67
|
readonly runnerHealth?: "ping" | "k8s" | undefined
|
|
@@ -127,7 +128,9 @@ export const layer = <
|
|
|
127
128
|
),
|
|
128
129
|
Layer.provide(ShardingConfig.layerFromEnv(options?.shardingConfig)),
|
|
129
130
|
Layer.provide(
|
|
130
|
-
options?.serialization === "ndjson"
|
|
131
|
+
options?.serialization === "ndjson"
|
|
132
|
+
? RpcSerialization.layerNdjsonWith({ maxBufferSize: options.serializationMaxBufferSize })
|
|
133
|
+
: RpcSerialization.layerMsgPackWith({ maxBufferSize: options.serializationMaxBufferSize })
|
|
131
134
|
)
|
|
132
135
|
) as any
|
|
133
136
|
}
|
package/src/NodeClusterSocket.ts
CHANGED
|
@@ -66,6 +66,7 @@ export const layer = <
|
|
|
66
66
|
>(
|
|
67
67
|
options?: {
|
|
68
68
|
readonly serialization?: "msgpack" | "ndjson" | undefined
|
|
69
|
+
readonly serializationMaxBufferSize?: number | "unbounded" | undefined
|
|
69
70
|
readonly clientOnly?: ClientOnly | undefined
|
|
70
71
|
readonly storage?: Storage | undefined
|
|
71
72
|
readonly runnerHealth?: "ping" | "k8s" | undefined
|
|
@@ -125,7 +126,9 @@ export const layer = <
|
|
|
125
126
|
),
|
|
126
127
|
Layer.provide(ShardingConfig.layerFromEnv(options?.shardingConfig)),
|
|
127
128
|
Layer.provide(
|
|
128
|
-
options?.serialization === "ndjson"
|
|
129
|
+
options?.serialization === "ndjson"
|
|
130
|
+
? RpcSerialization.layerNdjsonWith({ maxBufferSize: options?.serializationMaxBufferSize })
|
|
131
|
+
: RpcSerialization.layerMsgPackWith({ maxBufferSize: options?.serializationMaxBufferSize })
|
|
129
132
|
)
|
|
130
133
|
) as any
|
|
131
134
|
}
|
|
@@ -147,6 +150,8 @@ export const layerDispatcherK8s: Layer.Layer<NodeHttpClient.Dispatcher> = Layer.
|
|
|
147
150
|
if (caCertOption._tag === "Some") {
|
|
148
151
|
return yield* Effect.acquireRelease(
|
|
149
152
|
Effect.sync(() =>
|
|
153
|
+
// oxlint cannot resolve values re-exported through the local Undici facade.
|
|
154
|
+
// oxlint-disable-next-line import/namespace
|
|
150
155
|
new Undici.Agent({
|
|
151
156
|
connect: {
|
|
152
157
|
ca: caCertOption.value
|
package/src/NodeHttpClient.ts
CHANGED
|
@@ -51,14 +51,14 @@ export {
|
|
|
51
51
|
* Use to access or override the fetch implementation used by the Node
|
|
52
52
|
* fetch-based HTTP client.
|
|
53
53
|
*
|
|
54
|
-
* @category
|
|
54
|
+
* @category services
|
|
55
55
|
* @since 4.0.0
|
|
56
56
|
*/
|
|
57
57
|
Fetch,
|
|
58
58
|
/**
|
|
59
59
|
* Layer that provides the fetch-based HTTP client implementation.
|
|
60
60
|
*
|
|
61
|
-
* @category
|
|
61
|
+
* @category layers
|
|
62
62
|
* @since 4.0.0
|
|
63
63
|
*/
|
|
64
64
|
layer as layerFetch,
|
|
@@ -69,7 +69,7 @@ export {
|
|
|
69
69
|
*
|
|
70
70
|
* Use to provide default fetch request options for Node HTTP requests.
|
|
71
71
|
*
|
|
72
|
-
* @category
|
|
72
|
+
* @category services
|
|
73
73
|
* @since 4.0.0
|
|
74
74
|
*/
|
|
75
75
|
RequestInit
|
|
@@ -83,7 +83,7 @@ export {
|
|
|
83
83
|
* Service tag for the Undici `Dispatcher` used by the Undici-backed HTTP
|
|
84
84
|
* client.
|
|
85
85
|
*
|
|
86
|
-
* @category
|
|
86
|
+
* @category services
|
|
87
87
|
* @since 4.0.0
|
|
88
88
|
*/
|
|
89
89
|
export class Dispatcher extends Context.Service<Dispatcher, Undici.Dispatcher>()(
|
|
@@ -94,10 +94,12 @@ export class Dispatcher extends Context.Service<Dispatcher, Undici.Dispatcher>()
|
|
|
94
94
|
* Acquires a new Undici `Agent` dispatcher and destroys it when the enclosing
|
|
95
95
|
* scope is finalized.
|
|
96
96
|
*
|
|
97
|
-
* @category
|
|
97
|
+
* @category resource management
|
|
98
98
|
* @since 4.0.0
|
|
99
99
|
*/
|
|
100
100
|
export const makeDispatcher: Effect.Effect<Undici.Dispatcher, never, Scope.Scope> = Effect.acquireRelease(
|
|
101
|
+
// oxlint cannot resolve values re-exported through the local Undici facade.
|
|
102
|
+
// oxlint-disable-next-line import/namespace
|
|
101
103
|
Effect.sync(() => new Undici.Agent()),
|
|
102
104
|
(dispatcher) => Effect.promise(() => dispatcher.destroy())
|
|
103
105
|
)
|
|
@@ -105,7 +107,7 @@ export const makeDispatcher: Effect.Effect<Undici.Dispatcher, never, Scope.Scope
|
|
|
105
107
|
/**
|
|
106
108
|
* Provides the `Dispatcher` service using a scoped Undici `Agent`.
|
|
107
109
|
*
|
|
108
|
-
* @category
|
|
110
|
+
* @category layers
|
|
109
111
|
* @since 4.0.0
|
|
110
112
|
*/
|
|
111
113
|
export const layerDispatcher: Layer.Layer<Dispatcher> = Layer.effect(Dispatcher)(makeDispatcher)
|
|
@@ -114,16 +116,18 @@ export const layerDispatcher: Layer.Layer<Dispatcher> = Layer.effect(Dispatcher)
|
|
|
114
116
|
* Provides the `Dispatcher` service from Undici's process-global dispatcher,
|
|
115
117
|
* without creating or owning a new agent.
|
|
116
118
|
*
|
|
117
|
-
* @category
|
|
119
|
+
* @category layers
|
|
118
120
|
* @since 4.0.0
|
|
119
121
|
*/
|
|
122
|
+
// oxlint cannot resolve values re-exported through the local Undici facade.
|
|
123
|
+
// oxlint-disable-next-line import/namespace
|
|
120
124
|
export const dispatcherLayerGlobal: Layer.Layer<Dispatcher> = Layer.sync(Dispatcher)(() => Undici.getGlobalDispatcher())
|
|
121
125
|
|
|
122
126
|
/**
|
|
123
127
|
* Fiber reference containing default Undici request options applied to requests
|
|
124
128
|
* sent by `makeUndici`.
|
|
125
129
|
*
|
|
126
|
-
* @category
|
|
130
|
+
* @category services
|
|
127
131
|
* @since 4.0.0
|
|
128
132
|
*/
|
|
129
133
|
export const UndiciOptions = Context.Reference<Partial<Undici.Dispatcher.RequestOptions>>(
|
|
@@ -136,7 +140,7 @@ export const UndiciOptions = Context.Reference<Partial<Undici.Dispatcher.Request
|
|
|
136
140
|
* `Dispatcher`, converts Effect HTTP bodies to Undici bodies, and maps
|
|
137
141
|
* transport and decode failures to `HttpClientError`.
|
|
138
142
|
*
|
|
139
|
-
* @category
|
|
143
|
+
* @category constructors
|
|
140
144
|
* @since 4.0.0
|
|
141
145
|
*/
|
|
142
146
|
export const makeUndici = Effect.gen(function*() {
|
|
@@ -353,7 +357,7 @@ class UndiciResponse extends Inspectable.Class implements HttpClientResponse, Pi
|
|
|
353
357
|
* Provides an Undici-backed `HttpClient` using the current `Dispatcher`
|
|
354
358
|
* service.
|
|
355
359
|
*
|
|
356
|
-
* @category
|
|
360
|
+
* @category layers
|
|
357
361
|
* @since 4.0.0
|
|
358
362
|
*/
|
|
359
363
|
export const layerUndiciNoDispatcher: Layer.Layer<
|
|
@@ -366,7 +370,7 @@ export const layerUndiciNoDispatcher: Layer.Layer<
|
|
|
366
370
|
* Provides an Undici-backed `HttpClient` together with a scoped default
|
|
367
371
|
* Undici `Agent` dispatcher.
|
|
368
372
|
*
|
|
369
|
-
* @category
|
|
373
|
+
* @category layers
|
|
370
374
|
* @since 4.0.0
|
|
371
375
|
*/
|
|
372
376
|
export const layerUndici: Layer.Layer<Client.HttpClient> = Layer.provide(layerUndiciNoDispatcher, layerDispatcher)
|
|
@@ -379,7 +383,7 @@ export const layerUndici: Layer.Layer<Client.HttpClient> = Layer.provide(layerUn
|
|
|
379
383
|
* Service tag for the paired Node `http` and `https` agents used by the
|
|
380
384
|
* node:http-backed HTTP client.
|
|
381
385
|
*
|
|
382
|
-
* @category
|
|
386
|
+
* @category services
|
|
383
387
|
* @since 4.0.0
|
|
384
388
|
*/
|
|
385
389
|
export class HttpAgent extends Context.Service<HttpAgent, {
|
|
@@ -391,7 +395,7 @@ export class HttpAgent extends Context.Service<HttpAgent, {
|
|
|
391
395
|
* Acquires Node `http` and `https` agents with the supplied options and
|
|
392
396
|
* destroys both agents when the enclosing scope is finalized.
|
|
393
397
|
*
|
|
394
|
-
* @category
|
|
398
|
+
* @category resource management
|
|
395
399
|
* @since 4.0.0
|
|
396
400
|
*/
|
|
397
401
|
export const makeAgent = (options?: Https.AgentOptions): Effect.Effect<HttpAgent["Service"], never, Scope.Scope> =>
|
|
@@ -411,7 +415,7 @@ export const makeAgent = (options?: Https.AgentOptions): Effect.Effect<HttpAgent
|
|
|
411
415
|
* Provides the `HttpAgent` service using scoped Node `http` and `https`
|
|
412
416
|
* agents configured with the supplied options.
|
|
413
417
|
*
|
|
414
|
-
* @category
|
|
418
|
+
* @category layers
|
|
415
419
|
* @since 4.0.0
|
|
416
420
|
*/
|
|
417
421
|
export const layerAgentOptions: (options?: Https.AgentOptions | undefined) => Layer.Layer<
|
|
@@ -422,7 +426,7 @@ export const layerAgentOptions: (options?: Https.AgentOptions | undefined) => La
|
|
|
422
426
|
* Provides the `HttpAgent` service using default scoped Node `http` and
|
|
423
427
|
* `https` agents.
|
|
424
428
|
*
|
|
425
|
-
* @category
|
|
429
|
+
* @category layers
|
|
426
430
|
* @since 4.0.0
|
|
427
431
|
*/
|
|
428
432
|
export const layerAgent: Layer.Layer<HttpAgent> = layerAgentOptions()
|
|
@@ -432,7 +436,7 @@ export const layerAgent: Layer.Layer<HttpAgent> = layerAgentOptions()
|
|
|
432
436
|
* current `HttpAgent`, streaming request bodies, and wrapping Node responses
|
|
433
437
|
* as `HttpClientResponse` values.
|
|
434
438
|
*
|
|
435
|
-
* @category
|
|
439
|
+
* @category constructors
|
|
436
440
|
* @since 4.0.0
|
|
437
441
|
*/
|
|
438
442
|
export const makeNodeHttp = Effect.gen(function*() {
|
|
@@ -645,7 +649,7 @@ class NodeHttpResponse extends NodeHttpIncomingMessage<Error.HttpClientError> im
|
|
|
645
649
|
* Provides a node:http-backed `HttpClient` using the current `HttpAgent`
|
|
646
650
|
* service.
|
|
647
651
|
*
|
|
648
|
-
* @category
|
|
652
|
+
* @category layers
|
|
649
653
|
* @since 4.0.0
|
|
650
654
|
*/
|
|
651
655
|
export const layerNodeHttpNoAgent: Layer.Layer<
|
|
@@ -658,7 +662,7 @@ export const layerNodeHttpNoAgent: Layer.Layer<
|
|
|
658
662
|
* Provides a node:http-backed `HttpClient` together with default scoped Node
|
|
659
663
|
* `http` and `https` agents.
|
|
660
664
|
*
|
|
661
|
-
* @category
|
|
665
|
+
* @category layers
|
|
662
666
|
* @since 4.0.0
|
|
663
667
|
*/
|
|
664
668
|
export const layerNodeHttp: Layer.Layer<Client.HttpClient> = Layer.provide(layerNodeHttpNoAgent, layerAgent)
|
package/src/NodeHttpPlatform.ts
CHANGED
|
@@ -8,16 +8,63 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @since 4.0.0
|
|
10
10
|
*/
|
|
11
|
+
import * as NodeHttpCompression from "@effect/platform-node-shared/NodeHttpCompression"
|
|
12
|
+
import * as Effect from "effect/Effect"
|
|
11
13
|
import { pipe } from "effect/Function"
|
|
12
14
|
import * as Layer from "effect/Layer"
|
|
13
15
|
import * as EtagImpl from "effect/unstable/http/Etag"
|
|
14
16
|
import * as Headers from "effect/unstable/http/Headers"
|
|
17
|
+
import * as HttpBody from "effect/unstable/http/HttpBody"
|
|
15
18
|
import * as Platform from "effect/unstable/http/HttpPlatform"
|
|
16
19
|
import * as ServerResponse from "effect/unstable/http/HttpServerResponse"
|
|
17
20
|
import * as Fs from "node:fs"
|
|
18
21
|
import { Readable } from "node:stream"
|
|
19
22
|
import Mime from "./Mime.ts"
|
|
20
23
|
import * as NodeFileSystem from "./NodeFileSystem.ts"
|
|
24
|
+
import * as NodeStream from "./NodeStream.ts"
|
|
25
|
+
|
|
26
|
+
// replaces the response body while keeping every other field, dropping the
|
|
27
|
+
// now-stale Content-Length header
|
|
28
|
+
const compressedBody = (
|
|
29
|
+
response: ServerResponse.HttpServerResponse,
|
|
30
|
+
body: HttpBody.HttpBody
|
|
31
|
+
): ServerResponse.HttpServerResponse =>
|
|
32
|
+
ServerResponse.removeHeader(ServerResponse.setBody(response, body), "content-length")
|
|
33
|
+
|
|
34
|
+
const compression = NodeHttpCompression.make({
|
|
35
|
+
algorithms: NodeHttpCompression.algorithms,
|
|
36
|
+
compressResponse(response, algorithm, options) {
|
|
37
|
+
const body = response.body
|
|
38
|
+
switch (body._tag) {
|
|
39
|
+
case "Stream": {
|
|
40
|
+
return Effect.succeed(compressedBody(
|
|
41
|
+
response,
|
|
42
|
+
HttpBody.stream(
|
|
43
|
+
NodeStream.pipeThroughDuplex(body.stream, {
|
|
44
|
+
evaluate: () => NodeHttpCompression.compressTransform(algorithm, options)
|
|
45
|
+
}),
|
|
46
|
+
body.contentType
|
|
47
|
+
)
|
|
48
|
+
))
|
|
49
|
+
}
|
|
50
|
+
case "Raw": {
|
|
51
|
+
const readable = body.body instanceof Readable
|
|
52
|
+
? body.body
|
|
53
|
+
: Readable.fromWeb(new Response(body.body as BodyInit).body as any)
|
|
54
|
+
const transform = NodeHttpCompression.compressTransform(algorithm, options)
|
|
55
|
+
readable.on("error", (cause) => transform.destroy(cause))
|
|
56
|
+
transform.on("error", (cause) => readable.destroy(cause))
|
|
57
|
+
transform.on("close", () => readable.destroy())
|
|
58
|
+
return Effect.succeed(
|
|
59
|
+
compressedBody(response, HttpBody.raw(readable.pipe(transform), { contentType: body.contentType }))
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
default: {
|
|
63
|
+
return Effect.succeed(response)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
})
|
|
21
68
|
|
|
22
69
|
/**
|
|
23
70
|
* Creates the Node `HttpPlatform`, serving file responses from Node readable
|
|
@@ -27,6 +74,8 @@ import * as NodeFileSystem from "./NodeFileSystem.ts"
|
|
|
27
74
|
* @since 4.0.0
|
|
28
75
|
*/
|
|
29
76
|
export const make = Platform.make({
|
|
77
|
+
platform: "node",
|
|
78
|
+
compression,
|
|
30
79
|
fileResponse(path, status, statusText, headers, start, end, contentLength) {
|
|
31
80
|
const stream = contentLength === 0
|
|
32
81
|
? Readable.from([])
|
package/src/NodeHttpServer.ts
CHANGED
|
@@ -62,6 +62,26 @@ import * as NodeMultipart from "./NodeMultipart.ts"
|
|
|
62
62
|
import * as NodeServices from "./NodeServices.ts"
|
|
63
63
|
import { NodeWS } from "./NodeSocket.ts"
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Options accepted by the Node `HttpServer` constructors and layers.
|
|
67
|
+
*
|
|
68
|
+
* @category options
|
|
69
|
+
* @since 4.0.0
|
|
70
|
+
*/
|
|
71
|
+
export interface Options extends Net.ListenOptions {
|
|
72
|
+
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
73
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
74
|
+
/**
|
|
75
|
+
* Options forwarded to the underlying `ws` `WebSocketServer`, minus the
|
|
76
|
+
* wiring options the server manages itself. Use this to enable
|
|
77
|
+
* `permessage-deflate` compression or tune payload limits, e.g.
|
|
78
|
+
* `websocket: { perMessageDeflate: true }`.
|
|
79
|
+
*/
|
|
80
|
+
readonly websocket?:
|
|
81
|
+
| Omit<NodeWS.ServerOptions, "noServer" | "server" | "host" | "port" | "path">
|
|
82
|
+
| undefined
|
|
83
|
+
}
|
|
84
|
+
|
|
65
85
|
/**
|
|
66
86
|
* Creates a scoped `HttpServer` from a Node `http.Server`, starts listening
|
|
67
87
|
* with the supplied options, registers request and upgrade handling, and closes
|
|
@@ -72,10 +92,7 @@ import { NodeWS } from "./NodeSocket.ts"
|
|
|
72
92
|
*/
|
|
73
93
|
export const make = Effect.fnUntraced(function*(
|
|
74
94
|
evaluate: LazyArg<Http.Server>,
|
|
75
|
-
options:
|
|
76
|
-
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
77
|
-
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
78
|
-
}
|
|
95
|
+
options: Options
|
|
79
96
|
) {
|
|
80
97
|
const scope = yield* Effect.scope
|
|
81
98
|
const server = evaluate()
|
|
@@ -116,7 +133,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
116
133
|
const address = server.address()!
|
|
117
134
|
|
|
118
135
|
const wss = yield* Effect.acquireRelease(
|
|
119
|
-
Effect.sync(() => new NodeWS.WebSocketServer({ noServer: true })),
|
|
136
|
+
Effect.sync(() => new NodeWS.WebSocketServer({ ...options.websocket, noServer: true })),
|
|
120
137
|
(wss) =>
|
|
121
138
|
Effect.callback<void>((resume) => {
|
|
122
139
|
wss.close(() => resume(Effect.void))
|
|
@@ -189,9 +206,8 @@ export const makeHandler = <
|
|
|
189
206
|
nodeRequest: Http.IncomingMessage,
|
|
190
207
|
nodeResponse: Http.ServerResponse
|
|
191
208
|
) {
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
const fiber = Fiber.runIn(Effect.runForkWith(Context.makeUnsafe<any>(map))(handled), options.scope)
|
|
209
|
+
const context = Context.add(services, HttpServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse))
|
|
210
|
+
const fiber = Fiber.runIn(Effect.runForkWith(context as Context.Context<any>)(handled), options.scope)
|
|
195
211
|
nodeResponse.on("close", () => {
|
|
196
212
|
if (!nodeResponse.writableEnded) {
|
|
197
213
|
fiber.interruptUnsafe(parent.id, ClientAbort.annotation)
|
|
@@ -256,9 +272,12 @@ export const makeUpgradeHandler = <
|
|
|
256
272
|
(ws) => Effect.sync(() => ws.close())
|
|
257
273
|
)
|
|
258
274
|
))
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
275
|
+
const context = Context.add(
|
|
276
|
+
services,
|
|
277
|
+
HttpServerRequest,
|
|
278
|
+
new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect)
|
|
279
|
+
)
|
|
280
|
+
const fiber = Fiber.runIn(Effect.runForkWith(context as Context.Context<any>)(handledApp), options.scope)
|
|
262
281
|
socket.on("close", () => {
|
|
263
282
|
if (!socket.writableEnded) {
|
|
264
283
|
fiber.interruptUnsafe(parent.id, ClientAbort.annotation)
|
|
@@ -330,8 +349,9 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
330
349
|
return this.source.url!
|
|
331
350
|
}
|
|
332
351
|
|
|
352
|
+
private cachedMethod: HttpMethod | undefined
|
|
333
353
|
get method(): HttpMethod {
|
|
334
|
-
return this.source.method!.toUpperCase() as HttpMethod
|
|
354
|
+
return this.cachedMethod ??= this.source.method!.toUpperCase() as HttpMethod
|
|
335
355
|
}
|
|
336
356
|
|
|
337
357
|
override get headers(): Headers.Headers {
|
|
@@ -397,10 +417,7 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
397
417
|
*/
|
|
398
418
|
export const layerServer: (
|
|
399
419
|
evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>,
|
|
400
|
-
options:
|
|
401
|
-
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
402
|
-
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
403
|
-
}
|
|
420
|
+
options: Options
|
|
404
421
|
) => Layer.Layer<HttpServer.HttpServer, ServeError> = flow(make, Layer.effect(HttpServer.HttpServer))
|
|
405
422
|
|
|
406
423
|
/**
|
|
@@ -427,10 +444,7 @@ export const layerHttpServices: Layer.Layer<
|
|
|
427
444
|
*/
|
|
428
445
|
export const layer = (
|
|
429
446
|
evaluate: LazyArg<Http.Server>,
|
|
430
|
-
options:
|
|
431
|
-
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
432
|
-
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
433
|
-
}
|
|
447
|
+
options: Options
|
|
434
448
|
): Layer.Layer<
|
|
435
449
|
HttpServer.HttpServer | NodeServices.NodeServices | HttpPlatform.HttpPlatform | Etag.Generator,
|
|
436
450
|
ServeError
|
|
@@ -450,12 +464,7 @@ export const layer = (
|
|
|
450
464
|
*/
|
|
451
465
|
export const layerConfig = (
|
|
452
466
|
evaluate: LazyArg<Http.Server>,
|
|
453
|
-
options: Config.Wrap<
|
|
454
|
-
Net.ListenOptions & {
|
|
455
|
-
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
456
|
-
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
457
|
-
}
|
|
458
|
-
>
|
|
467
|
+
options: Config.Wrap<Options>
|
|
459
468
|
): Layer.Layer<
|
|
460
469
|
HttpServer.HttpServer | NodeServices.NodeServices | HttpPlatform.HttpPlatform | Etag.Generator,
|
|
461
470
|
ServeError | Config.ConfigError
|
|
@@ -517,14 +526,20 @@ const handleResponse = (
|
|
|
517
526
|
|
|
518
527
|
if (request.method === "HEAD") {
|
|
519
528
|
nodeResponse.writeHead(response.status, headers)
|
|
520
|
-
return Effect.
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
529
|
+
return Effect.andThen(
|
|
530
|
+
cancelResponseBody(response.body),
|
|
531
|
+
Effect.callback<void>((resume) => {
|
|
532
|
+
let completed = false
|
|
533
|
+
const done = () => {
|
|
534
|
+
if (completed) return
|
|
535
|
+
completed = true
|
|
536
|
+
nodeResponse.off("close", done)
|
|
537
|
+
resume(Effect.void)
|
|
538
|
+
}
|
|
539
|
+
nodeResponse.once("close", done)
|
|
540
|
+
nodeResponse.end(done)
|
|
541
|
+
})
|
|
542
|
+
)
|
|
528
543
|
}
|
|
529
544
|
const body = response.body
|
|
530
545
|
switch (body._tag) {
|
|
@@ -608,17 +623,9 @@ const handleResponse = (
|
|
|
608
623
|
return body.stream.pipe(
|
|
609
624
|
Stream.orDie,
|
|
610
625
|
Stream.runForEachArray((array) => {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if (!written && !needDrain) {
|
|
615
|
-
needDrain = true
|
|
616
|
-
drainLatch.closeUnsafe()
|
|
617
|
-
} else if (written && needDrain) {
|
|
618
|
-
needDrain = false
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
if (!needDrain) return Effect.void
|
|
626
|
+
const chunk = array.length > 1 ? Buffer.concat(array) : array[0]
|
|
627
|
+
if (nodeResponse.write(chunk)) return Effect.void
|
|
628
|
+
drainLatch.closeUnsafe()
|
|
622
629
|
return drainLatch.await
|
|
623
630
|
}),
|
|
624
631
|
Effect.interruptible,
|
|
@@ -631,6 +638,14 @@ const handleResponse = (
|
|
|
631
638
|
}
|
|
632
639
|
}
|
|
633
640
|
|
|
641
|
+
const cancelResponseBody = (body: HttpServerResponse["body"]): Effect.Effect<void> => {
|
|
642
|
+
const stream = body._tag === "Raw" ? body.body : undefined
|
|
643
|
+
if (stream instanceof Readable) {
|
|
644
|
+
return Effect.sync(() => stream.destroy())
|
|
645
|
+
}
|
|
646
|
+
return Effect.void
|
|
647
|
+
}
|
|
648
|
+
|
|
634
649
|
const handleCause = (
|
|
635
650
|
nodeResponse: Http.ServerResponse,
|
|
636
651
|
originalResponse: HttpServerResponse
|
package/src/NodeWorkerRunner.ts
CHANGED
|
@@ -16,6 +16,7 @@ import * as Effect from "effect/Effect"
|
|
|
16
16
|
import * as Exit from "effect/Exit"
|
|
17
17
|
import * as Fiber from "effect/Fiber"
|
|
18
18
|
import * as Layer from "effect/Layer"
|
|
19
|
+
import * as Scope from "effect/Scope"
|
|
19
20
|
import { WorkerError, WorkerReceiveError, WorkerSpawnError } from "effect/unstable/workers/WorkerError"
|
|
20
21
|
import * as WorkerRunner from "effect/unstable/workers/WorkerRunner"
|
|
21
22
|
import * as WorkerThreads from "node:worker_threads"
|
|
@@ -56,7 +57,8 @@ export const layer: Layer.Layer<WorkerRunner.WorkerRunnerPlatform> = Layer.succe
|
|
|
56
57
|
runFork(Effect.logError("unhandled error in worker", exit.cause))
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
const port = WorkerThreads.parentPort ?? process
|
|
61
|
+
function onMessage(message: WorkerRunner.PlatformMessage<I>) {
|
|
60
62
|
if (message[0] === 0) {
|
|
61
63
|
const result = handler(0, message[1])
|
|
62
64
|
if (Effect.isEffect(result)) {
|
|
@@ -72,32 +74,46 @@ export const layer: Layer.Layer<WorkerRunner.WorkerRunnerPlatform> = Layer.succe
|
|
|
72
74
|
}
|
|
73
75
|
Deferred.doneUnsafe(closeLatch, Exit.void)
|
|
74
76
|
}
|
|
75
|
-
}
|
|
77
|
+
}
|
|
78
|
+
port.on("message", onMessage)
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
new
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
cause
|
|
85
|
-
})
|
|
80
|
+
function onMessageError(cause: unknown) {
|
|
81
|
+
Deferred.doneUnsafe(
|
|
82
|
+
closeLatch,
|
|
83
|
+
new WorkerError({
|
|
84
|
+
reason: new WorkerReceiveError({
|
|
85
|
+
message: "received messageerror event",
|
|
86
|
+
cause
|
|
86
87
|
})
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
function onError(cause: unknown) {
|
|
92
|
+
Deferred.doneUnsafe(
|
|
93
|
+
closeLatch,
|
|
94
|
+
new WorkerError({
|
|
95
|
+
reason: new WorkerReceiveError({
|
|
96
|
+
message: "received error event",
|
|
97
|
+
cause
|
|
97
98
|
})
|
|
98
|
-
)
|
|
99
|
-
|
|
99
|
+
})
|
|
100
|
+
)
|
|
100
101
|
}
|
|
102
|
+
if (WorkerThreads.parentPort) {
|
|
103
|
+
WorkerThreads.parentPort.on("messageerror", onMessageError)
|
|
104
|
+
WorkerThreads.parentPort.on("error", onError)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
yield* Scope.addFinalizer(
|
|
108
|
+
scope,
|
|
109
|
+
Effect.sync(() => {
|
|
110
|
+
port.off("message", onMessage)
|
|
111
|
+
if (WorkerThreads.parentPort) {
|
|
112
|
+
WorkerThreads.parentPort.off("messageerror", onMessageError)
|
|
113
|
+
WorkerThreads.parentPort.off("error", onError)
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
)
|
|
101
117
|
|
|
102
118
|
sendUnsafe(0, [0])
|
|
103
119
|
|
package/src/Undici.ts
CHANGED
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
import Undici from "undici"
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @category
|
|
20
|
+
* @category re-exports
|
|
21
21
|
* @since 4.0.0
|
|
22
22
|
*/
|
|
23
23
|
export * from "undici"
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* @category
|
|
26
|
+
* @category re-exports
|
|
27
27
|
* @since 4.0.0
|
|
28
28
|
*/
|
|
29
29
|
export default Undici
|