@effect/platform-node 4.0.0-beta.5 → 4.0.0-beta.50
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/NodeClusterHttp.d.ts.map +1 -1
- package/dist/NodeClusterHttp.js +5 -4
- package/dist/NodeClusterHttp.js.map +1 -1
- package/dist/NodeHttpClient.d.ts +4 -4
- package/dist/NodeHttpClient.d.ts.map +1 -1
- package/dist/NodeHttpClient.js +15 -7
- package/dist/NodeHttpClient.js.map +1 -1
- package/dist/NodeHttpIncomingMessage.d.ts +7 -5
- package/dist/NodeHttpIncomingMessage.d.ts.map +1 -1
- package/dist/NodeHttpIncomingMessage.js +2 -1
- package/dist/NodeHttpIncomingMessage.js.map +1 -1
- package/dist/NodeHttpPlatform.d.ts.map +1 -1
- package/dist/NodeHttpPlatform.js +2 -2
- package/dist/NodeHttpPlatform.js.map +1 -1
- package/dist/NodeHttpServer.d.ts +17 -4
- package/dist/NodeHttpServer.d.ts.map +1 -1
- package/dist/NodeHttpServer.js +49 -36
- package/dist/NodeHttpServer.js.map +1 -1
- package/dist/NodeRedis.d.ts +2 -2
- package/dist/NodeRedis.d.ts.map +1 -1
- package/dist/NodeRedis.js +5 -5
- package/dist/NodeRedis.js.map +1 -1
- package/dist/NodeRuntime.d.ts +0 -3
- package/dist/NodeRuntime.d.ts.map +1 -1
- package/dist/NodeRuntime.js +0 -1
- package/dist/NodeRuntime.js.map +1 -1
- package/dist/NodeSocket.d.ts +6 -1
- package/dist/NodeSocket.d.ts.map +1 -1
- package/dist/NodeSocket.js +5 -0
- package/dist/NodeSocket.js.map +1 -1
- package/dist/NodeWorkerRunner.js +1 -1
- package/dist/NodeWorkerRunner.js.map +1 -1
- package/package.json +9 -9
- package/src/NodeClusterHttp.ts +5 -4
- package/src/NodeHttpClient.ts +23 -12
- package/src/NodeHttpIncomingMessage.ts +8 -6
- package/src/NodeHttpPlatform.ts +3 -1
- package/src/NodeHttpServer.ts +71 -40
- package/src/NodeRedis.ts +6 -6
- package/src/NodeRuntime.ts +0 -3
- package/src/NodeSocket.ts +11 -1
- package/src/NodeWorkerRunner.ts +1 -1
package/src/NodeHttpClient.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
+
import * as Context from "effect/Context"
|
|
4
5
|
import * as Effect from "effect/Effect"
|
|
5
6
|
import { flow } from "effect/Function"
|
|
6
7
|
import * as Inspectable from "effect/Inspectable"
|
|
7
8
|
import * as Layer from "effect/Layer"
|
|
9
|
+
import * as Option from "effect/Option"
|
|
10
|
+
import { type Pipeable, pipeArguments } from "effect/Pipeable"
|
|
11
|
+
import type * as Schema from "effect/Schema"
|
|
8
12
|
import type * as Scope from "effect/Scope"
|
|
9
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
10
13
|
import * as Stream from "effect/Stream"
|
|
11
14
|
import * as Cookies from "effect/unstable/http/Cookies"
|
|
12
15
|
import * as Headers from "effect/unstable/http/Headers"
|
|
@@ -57,7 +60,7 @@ export {
|
|
|
57
60
|
* @since 1.0.0
|
|
58
61
|
* @category Dispatcher
|
|
59
62
|
*/
|
|
60
|
-
export class Dispatcher extends
|
|
63
|
+
export class Dispatcher extends Context.Service<Dispatcher, Undici.Dispatcher>()(
|
|
61
64
|
"@effect/platform-node/NodeHttpClient/Dispatcher"
|
|
62
65
|
) {}
|
|
63
66
|
|
|
@@ -86,7 +89,7 @@ export const dispatcherLayerGlobal: Layer.Layer<Dispatcher> = Layer.sync(Dispatc
|
|
|
86
89
|
* @since 1.0.0
|
|
87
90
|
* @category undici
|
|
88
91
|
*/
|
|
89
|
-
export const UndiciOptions =
|
|
92
|
+
export const UndiciOptions = Context.Reference<Partial<Undici.Dispatcher.RequestOptions>>(
|
|
90
93
|
"@effect/platform-node/NodeHttpClient/UndiciOptions",
|
|
91
94
|
{ defaultValue: () => ({}) }
|
|
92
95
|
)
|
|
@@ -150,7 +153,7 @@ function convertBody(
|
|
|
150
153
|
|
|
151
154
|
function noopErrorHandler(_: any) {}
|
|
152
155
|
|
|
153
|
-
class UndiciResponse extends Inspectable.Class implements HttpClientResponse {
|
|
156
|
+
class UndiciResponse extends Inspectable.Class implements HttpClientResponse, Pipeable {
|
|
154
157
|
readonly [IncomingMessage.TypeId]: typeof IncomingMessage.TypeId
|
|
155
158
|
readonly [Response.TypeId]: typeof Response.TypeId
|
|
156
159
|
readonly request: HttpClientRequest
|
|
@@ -189,8 +192,8 @@ class UndiciResponse extends Inspectable.Class implements HttpClientResponse {
|
|
|
189
192
|
return this.cachedCookies = header ? Cookies.fromSetCookie(header) : Cookies.empty
|
|
190
193
|
}
|
|
191
194
|
|
|
192
|
-
get remoteAddress(): string
|
|
193
|
-
return
|
|
195
|
+
get remoteAddress(): Option.Option<string> {
|
|
196
|
+
return Option.none()
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
get stream(): Stream.Stream<Uint8Array, Error.HttpClientError> {
|
|
@@ -207,10 +210,10 @@ class UndiciResponse extends Inspectable.Class implements HttpClientResponse {
|
|
|
207
210
|
})
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
get json(): Effect.Effect<
|
|
213
|
+
get json(): Effect.Effect<Schema.Json, Error.HttpClientError> {
|
|
211
214
|
return Effect.flatMap(this.text, (text) =>
|
|
212
215
|
Effect.try({
|
|
213
|
-
try: () => text === "" ? null : JSON.parse(text)
|
|
216
|
+
try: () => text === "" ? null : JSON.parse(text),
|
|
214
217
|
catch: (cause) =>
|
|
215
218
|
new Error.HttpClientError({
|
|
216
219
|
reason: new Error.DecodeError({
|
|
@@ -289,6 +292,10 @@ class UndiciResponse extends Inspectable.Class implements HttpClientResponse {
|
|
|
289
292
|
status: this.status
|
|
290
293
|
})
|
|
291
294
|
}
|
|
295
|
+
|
|
296
|
+
pipe() {
|
|
297
|
+
return pipeArguments(this, arguments)
|
|
298
|
+
}
|
|
292
299
|
}
|
|
293
300
|
|
|
294
301
|
/**
|
|
@@ -299,7 +306,7 @@ export const layerUndiciNoDispatcher: Layer.Layer<
|
|
|
299
306
|
Client.HttpClient,
|
|
300
307
|
never,
|
|
301
308
|
Dispatcher
|
|
302
|
-
> = Client.
|
|
309
|
+
> = Client.layerMergedContext(makeUndici)
|
|
303
310
|
|
|
304
311
|
/**
|
|
305
312
|
* @since 1.0.0
|
|
@@ -315,7 +322,7 @@ export const layerUndici: Layer.Layer<Client.HttpClient> = Layer.provide(layerUn
|
|
|
315
322
|
* @since 1.0.0
|
|
316
323
|
* @category HttpAgent
|
|
317
324
|
*/
|
|
318
|
-
export class HttpAgent extends
|
|
325
|
+
export class HttpAgent extends Context.Service<HttpAgent, {
|
|
319
326
|
readonly http: Http.Agent
|
|
320
327
|
readonly https: Https.Agent
|
|
321
328
|
}>()("@effect/platform-node/NodeHttpClient/HttpAgent") {}
|
|
@@ -490,7 +497,7 @@ const waitForFinish = (nodeRequest: Http.ClientRequest, request: HttpClientReque
|
|
|
490
497
|
})
|
|
491
498
|
})
|
|
492
499
|
|
|
493
|
-
class NodeHttpResponse extends NodeHttpIncomingMessage<Error.HttpClientError> implements HttpClientResponse {
|
|
500
|
+
class NodeHttpResponse extends NodeHttpIncomingMessage<Error.HttpClientError> implements HttpClientResponse, Pipeable {
|
|
494
501
|
readonly [Response.TypeId]: typeof Response.TypeId
|
|
495
502
|
readonly request: HttpClientRequest
|
|
496
503
|
|
|
@@ -555,6 +562,10 @@ class NodeHttpResponse extends NodeHttpIncomingMessage<Error.HttpClientError> im
|
|
|
555
562
|
status: this.status
|
|
556
563
|
})
|
|
557
564
|
}
|
|
565
|
+
|
|
566
|
+
pipe() {
|
|
567
|
+
return pipeArguments(this, arguments)
|
|
568
|
+
}
|
|
558
569
|
}
|
|
559
570
|
|
|
560
571
|
/**
|
|
@@ -565,7 +576,7 @@ export const layerNodeHttpNoAgent: Layer.Layer<
|
|
|
565
576
|
Client.HttpClient,
|
|
566
577
|
never,
|
|
567
578
|
HttpAgent
|
|
568
|
-
> = Client.
|
|
579
|
+
> = Client.layerMergedContext(makeNodeHttp)
|
|
569
580
|
|
|
570
581
|
/**
|
|
571
582
|
* @since 1.0.0
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
5
|
import * as Inspectable from "effect/Inspectable"
|
|
6
|
+
import * as Option from "effect/Option"
|
|
7
|
+
import type * as Schema from "effect/Schema"
|
|
6
8
|
import type * as Stream from "effect/Stream"
|
|
7
9
|
import * as Headers from "effect/unstable/http/Headers"
|
|
8
10
|
import * as IncomingMessage from "effect/unstable/http/HttpIncomingMessage"
|
|
@@ -23,12 +25,12 @@ export abstract class NodeHttpIncomingMessage<E> extends Inspectable.Class
|
|
|
23
25
|
readonly [IncomingMessage.TypeId]: typeof IncomingMessage.TypeId
|
|
24
26
|
readonly source: Http.IncomingMessage
|
|
25
27
|
readonly onError: (error: unknown) => E
|
|
26
|
-
readonly remoteAddressOverride?: string | undefined
|
|
28
|
+
readonly remoteAddressOverride?: Option.Option<string> | undefined
|
|
27
29
|
|
|
28
30
|
constructor(
|
|
29
31
|
source: Http.IncomingMessage,
|
|
30
32
|
onError: (error: unknown) => E,
|
|
31
|
-
remoteAddressOverride?: string
|
|
33
|
+
remoteAddressOverride?: Option.Option<string>
|
|
32
34
|
) {
|
|
33
35
|
super()
|
|
34
36
|
this[IncomingMessage.TypeId] = IncomingMessage.TypeId
|
|
@@ -42,7 +44,7 @@ export abstract class NodeHttpIncomingMessage<E> extends Inspectable.Class
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
get remoteAddress() {
|
|
45
|
-
return this.remoteAddressOverride ?? this.source.socket.remoteAddress
|
|
47
|
+
return this.remoteAddressOverride ?? Option.fromNullishOr(this.source.socket.remoteAddress)
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
private textEffect: Effect.Effect<string, E> | undefined
|
|
@@ -67,15 +69,15 @@ export abstract class NodeHttpIncomingMessage<E> extends Inspectable.Class
|
|
|
67
69
|
return Effect.runSync(this.text)
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
get json(): Effect.Effect<
|
|
72
|
+
get json(): Effect.Effect<Schema.Json, E> {
|
|
71
73
|
return Effect.flatMap(this.text, (text) =>
|
|
72
74
|
Effect.try({
|
|
73
|
-
try: () => text === "" ? null : JSON.parse(text)
|
|
75
|
+
try: () => text === "" ? null : JSON.parse(text),
|
|
74
76
|
catch: this.onError
|
|
75
77
|
}))
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
get jsonUnsafe():
|
|
80
|
+
get jsonUnsafe(): Schema.Json {
|
|
79
81
|
return Effect.runSync(this.json)
|
|
80
82
|
}
|
|
81
83
|
|
package/src/NodeHttpPlatform.ts
CHANGED
|
@@ -18,7 +18,9 @@ import * as NodeFileSystem from "./NodeFileSystem.ts"
|
|
|
18
18
|
*/
|
|
19
19
|
export const make = Platform.make({
|
|
20
20
|
fileResponse(path, status, statusText, headers, start, end, contentLength) {
|
|
21
|
-
const stream =
|
|
21
|
+
const stream = contentLength === 0
|
|
22
|
+
? Readable.from([])
|
|
23
|
+
: Fs.createReadStream(path, { start, end: end === undefined ? undefined : end - 1 })
|
|
22
24
|
return ServerResponse.raw(stream, {
|
|
23
25
|
headers: {
|
|
24
26
|
...headers,
|
package/src/NodeHttpServer.ts
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import * as Cause from "effect/Cause"
|
|
5
5
|
import * as Config from "effect/Config"
|
|
6
|
+
import * as Context from "effect/Context"
|
|
7
|
+
import * as Duration from "effect/Duration"
|
|
6
8
|
import * as Effect from "effect/Effect"
|
|
7
9
|
import * as Fiber from "effect/Fiber"
|
|
8
10
|
import type * as FileSystem from "effect/FileSystem"
|
|
9
11
|
import { flow, type LazyArg } from "effect/Function"
|
|
12
|
+
import * as Latch from "effect/Latch"
|
|
10
13
|
import * as Layer from "effect/Layer"
|
|
14
|
+
import type * as Option from "effect/Option"
|
|
11
15
|
import type * as Path from "effect/Path"
|
|
12
16
|
import type * as Record from "effect/Record"
|
|
13
17
|
import * as Scope from "effect/Scope"
|
|
14
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
15
18
|
import * as Stream from "effect/Stream"
|
|
16
19
|
import * as Cookies from "effect/unstable/http/Cookies"
|
|
17
20
|
import * as Etag from "effect/unstable/http/Etag"
|
|
@@ -26,7 +29,7 @@ import type * as HttpPlatform from "effect/unstable/http/HttpPlatform"
|
|
|
26
29
|
import * as HttpServer from "effect/unstable/http/HttpServer"
|
|
27
30
|
import {
|
|
28
31
|
causeResponse,
|
|
29
|
-
|
|
32
|
+
ClientAbort,
|
|
30
33
|
HttpServerError,
|
|
31
34
|
RequestParseError,
|
|
32
35
|
ResponseError,
|
|
@@ -54,25 +57,35 @@ import { NodeWS } from "./NodeSocket.ts"
|
|
|
54
57
|
*/
|
|
55
58
|
export const make = Effect.fnUntraced(function*(
|
|
56
59
|
evaluate: LazyArg<Http.Server>,
|
|
57
|
-
options: Net.ListenOptions
|
|
60
|
+
options: Net.ListenOptions & {
|
|
61
|
+
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
62
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
63
|
+
}
|
|
58
64
|
) {
|
|
59
65
|
const scope = yield* Effect.scope
|
|
60
66
|
const server = evaluate()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
|
|
68
|
+
const shutdown = yield* Effect.callback<void>((resume) => {
|
|
69
|
+
if (!server.listening) {
|
|
70
|
+
return resume(Effect.void)
|
|
71
|
+
}
|
|
72
|
+
server.close((error) => {
|
|
73
|
+
if (error) {
|
|
74
|
+
resume(Effect.die(error))
|
|
75
|
+
} else {
|
|
76
|
+
resume(Effect.void)
|
|
66
77
|
}
|
|
67
|
-
server.close((error) => {
|
|
68
|
-
if (error) {
|
|
69
|
-
resume(Effect.die(error))
|
|
70
|
-
} else {
|
|
71
|
-
resume(Effect.void)
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
78
|
})
|
|
75
|
-
)
|
|
79
|
+
}).pipe(Effect.cached)
|
|
80
|
+
|
|
81
|
+
const preemptiveShutdown = options.disablePreemptiveShutdown ?
|
|
82
|
+
Effect.void :
|
|
83
|
+
Effect.timeoutOrElse(shutdown, {
|
|
84
|
+
duration: options.gracefulShutdownTimeout ?? Duration.seconds(20),
|
|
85
|
+
orElse: () => Effect.void
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
yield* Scope.addFinalizer(scope, shutdown)
|
|
76
89
|
|
|
77
90
|
yield* Effect.callback<void, ServeError>((resume) => {
|
|
78
91
|
function onError(cause: Error) {
|
|
@@ -110,7 +123,8 @@ export const make = Effect.fnUntraced(function*(
|
|
|
110
123
|
port: address.port
|
|
111
124
|
},
|
|
112
125
|
serve: Effect.fnUntraced(function*(httpApp, middleware) {
|
|
113
|
-
const
|
|
126
|
+
const serveScope = yield* Effect.scope
|
|
127
|
+
const scope = Scope.forkUnsafe(serveScope, "parallel")
|
|
114
128
|
const handler = yield* (makeHandler(httpApp, {
|
|
115
129
|
middleware: middleware as any,
|
|
116
130
|
scope
|
|
@@ -119,12 +133,11 @@ export const make = Effect.fnUntraced(function*(
|
|
|
119
133
|
middleware: middleware as any,
|
|
120
134
|
scope
|
|
121
135
|
})
|
|
122
|
-
yield*
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
)
|
|
136
|
+
yield* Scope.addFinalizerExit(serveScope, () => {
|
|
137
|
+
server.off("request", handler)
|
|
138
|
+
server.off("upgrade", upgradeHandler)
|
|
139
|
+
return preemptiveShutdown
|
|
140
|
+
})
|
|
128
141
|
server.on("request", handler)
|
|
129
142
|
server.on("upgrade", upgradeHandler)
|
|
130
143
|
})
|
|
@@ -151,20 +164,21 @@ export const makeHandler = <
|
|
|
151
164
|
Exclude<Effect.Services<App>, HttpServerRequest | Scope.Scope>
|
|
152
165
|
> => {
|
|
153
166
|
const handled = HttpEffect.toHandled(httpEffect, handleResponse, options.middleware as any)
|
|
154
|
-
return Effect.
|
|
155
|
-
|
|
167
|
+
return Effect.withFiber((parent) => {
|
|
168
|
+
const services = parent.context
|
|
169
|
+
return Effect.succeed(function handler(
|
|
156
170
|
nodeRequest: Http.IncomingMessage,
|
|
157
171
|
nodeResponse: Http.ServerResponse
|
|
158
172
|
) {
|
|
159
173
|
const map = new Map(services.mapUnsafe)
|
|
160
174
|
map.set(HttpServerRequest.key, new ServerRequestImpl(nodeRequest, nodeResponse))
|
|
161
|
-
const fiber = Fiber.runIn(Effect.runForkWith(
|
|
175
|
+
const fiber = Fiber.runIn(Effect.runForkWith(Context.makeUnsafe<any>(map))(handled), options.scope)
|
|
162
176
|
nodeResponse.on("close", () => {
|
|
163
177
|
if (!nodeResponse.writableEnded) {
|
|
164
|
-
fiber.interruptUnsafe(
|
|
178
|
+
fiber.interruptUnsafe(parent.id, ClientAbort.annotation)
|
|
165
179
|
}
|
|
166
180
|
})
|
|
167
|
-
}
|
|
181
|
+
})
|
|
168
182
|
})
|
|
169
183
|
}
|
|
170
184
|
|
|
@@ -189,8 +203,13 @@ export const makeUpgradeHandler = <
|
|
|
189
203
|
Exclude<Effect.Services<App>, HttpServerRequest | Scope.Scope>
|
|
190
204
|
> => {
|
|
191
205
|
const handledApp = HttpEffect.toHandled(httpEffect, handleResponse, options.middleware as any)
|
|
192
|
-
return Effect.
|
|
193
|
-
|
|
206
|
+
return Effect.withFiber((parent) => {
|
|
207
|
+
const services = parent.context
|
|
208
|
+
return Effect.succeed(function handler(
|
|
209
|
+
nodeRequest: Http.IncomingMessage,
|
|
210
|
+
socket: Duplex,
|
|
211
|
+
head: Buffer
|
|
212
|
+
) {
|
|
194
213
|
let nodeResponse_: Http.ServerResponse | undefined = undefined
|
|
195
214
|
const nodeResponse = () => {
|
|
196
215
|
if (nodeResponse_ === undefined) {
|
|
@@ -216,13 +235,14 @@ export const makeUpgradeHandler = <
|
|
|
216
235
|
))
|
|
217
236
|
const map = new Map(services.mapUnsafe)
|
|
218
237
|
map.set(HttpServerRequest.key, new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect))
|
|
219
|
-
const fiber = Fiber.runIn(Effect.runForkWith(
|
|
238
|
+
const fiber = Fiber.runIn(Effect.runForkWith(Context.makeUnsafe<any>(map))(handledApp), options.scope)
|
|
220
239
|
socket.on("close", () => {
|
|
221
240
|
if (!socket.writableEnded) {
|
|
222
|
-
fiber.interruptUnsafe(
|
|
241
|
+
fiber.interruptUnsafe(parent.id, ClientAbort.annotation)
|
|
223
242
|
}
|
|
224
243
|
})
|
|
225
|
-
})
|
|
244
|
+
})
|
|
245
|
+
})
|
|
226
246
|
}
|
|
227
247
|
|
|
228
248
|
class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> implements HttpServerRequest {
|
|
@@ -238,7 +258,7 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
238
258
|
upgradeEffect?: Effect.Effect<Socket.Socket, HttpServerError>,
|
|
239
259
|
url = source.url!,
|
|
240
260
|
headersOverride?: Headers.Headers,
|
|
241
|
-
remoteAddressOverride?: string
|
|
261
|
+
remoteAddressOverride?: Option.Option<string>
|
|
242
262
|
) {
|
|
243
263
|
super(source, (cause) =>
|
|
244
264
|
new HttpServerError({
|
|
@@ -270,7 +290,7 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
270
290
|
options: {
|
|
271
291
|
readonly url?: string | undefined
|
|
272
292
|
readonly headers?: Headers.Headers | undefined
|
|
273
|
-
readonly remoteAddress?: string | undefined
|
|
293
|
+
readonly remoteAddress?: Option.Option<string> | undefined
|
|
274
294
|
}
|
|
275
295
|
) {
|
|
276
296
|
return new ServerRequestImpl(
|
|
@@ -279,7 +299,7 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
279
299
|
this.upgradeEffect,
|
|
280
300
|
options.url ?? this.url,
|
|
281
301
|
options.headers ?? this.headersOverride,
|
|
282
|
-
options.remoteAddress
|
|
302
|
+
"remoteAddress" in options ? options.remoteAddress : this.remoteAddressOverride
|
|
283
303
|
)
|
|
284
304
|
}
|
|
285
305
|
|
|
@@ -351,7 +371,10 @@ class ServerRequestImpl extends NodeHttpIncomingMessage<HttpServerError> impleme
|
|
|
351
371
|
*/
|
|
352
372
|
export const layerServer: (
|
|
353
373
|
evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>,
|
|
354
|
-
options: Net.ListenOptions
|
|
374
|
+
options: Net.ListenOptions & {
|
|
375
|
+
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
376
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
377
|
+
}
|
|
355
378
|
) => Layer.Layer<HttpServer.HttpServer, ServeError> = flow(make, Layer.effect(HttpServer.HttpServer))
|
|
356
379
|
|
|
357
380
|
/**
|
|
@@ -372,7 +395,10 @@ export const layerHttpServices: Layer.Layer<
|
|
|
372
395
|
*/
|
|
373
396
|
export const layer = (
|
|
374
397
|
evaluate: LazyArg<Http.Server>,
|
|
375
|
-
options: Net.ListenOptions
|
|
398
|
+
options: Net.ListenOptions & {
|
|
399
|
+
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
400
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
401
|
+
}
|
|
376
402
|
): Layer.Layer<
|
|
377
403
|
HttpServer.HttpServer | NodeServices.NodeServices | HttpPlatform.HttpPlatform | Etag.Generator,
|
|
378
404
|
ServeError
|
|
@@ -388,7 +414,12 @@ export const layer = (
|
|
|
388
414
|
*/
|
|
389
415
|
export const layerConfig = (
|
|
390
416
|
evaluate: LazyArg<Http.Server>,
|
|
391
|
-
options: Config.Wrap<
|
|
417
|
+
options: Config.Wrap<
|
|
418
|
+
Net.ListenOptions & {
|
|
419
|
+
readonly disablePreemptiveShutdown?: boolean | undefined
|
|
420
|
+
readonly gracefulShutdownTimeout?: Duration.Input | undefined
|
|
421
|
+
}
|
|
422
|
+
>
|
|
392
423
|
): Layer.Layer<
|
|
393
424
|
HttpServer.HttpServer | FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform | Etag.Generator,
|
|
394
425
|
ServeError | Config.ConfigError
|
|
@@ -528,7 +559,7 @@ const handleResponse = (
|
|
|
528
559
|
}
|
|
529
560
|
case "Stream": {
|
|
530
561
|
nodeResponse.writeHead(response.status, headers)
|
|
531
|
-
const drainLatch =
|
|
562
|
+
const drainLatch = Latch.makeUnsafe()
|
|
532
563
|
nodeResponse.on("drain", () => drainLatch.openUnsafe())
|
|
533
564
|
return body.stream.pipe(
|
|
534
565
|
Stream.orDie,
|
package/src/NodeRedis.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Config from "effect/Config"
|
|
5
|
+
import * as Context from "effect/Context"
|
|
5
6
|
import * as Effect from "effect/Effect"
|
|
6
7
|
import * as Fn from "effect/Function"
|
|
7
8
|
import * as Layer from "effect/Layer"
|
|
8
9
|
import * as Scope from "effect/Scope"
|
|
9
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
10
10
|
import * as Redis from "effect/unstable/persistence/Redis"
|
|
11
11
|
import * as IoRedis from "ioredis"
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ import * as IoRedis from "ioredis"
|
|
|
14
14
|
* @since 1.0.0
|
|
15
15
|
* @category Service
|
|
16
16
|
*/
|
|
17
|
-
export class NodeRedis extends
|
|
17
|
+
export class NodeRedis extends Context.Service<NodeRedis, {
|
|
18
18
|
readonly client: IoRedis.Redis
|
|
19
19
|
readonly use: <A>(f: (client: IoRedis.Redis) => Promise<A>) => Effect.Effect<A, Redis.RedisError>
|
|
20
20
|
}>()("@effect/platform-node/NodeRedis") {}
|
|
@@ -45,8 +45,8 @@ const make = Effect.fnUntraced(function*(
|
|
|
45
45
|
use
|
|
46
46
|
})
|
|
47
47
|
|
|
48
|
-
return
|
|
49
|
-
|
|
48
|
+
return Context.make(NodeRedis, nodeRedis).pipe(
|
|
49
|
+
Context.add(Redis.Redis, redis)
|
|
50
50
|
)
|
|
51
51
|
})
|
|
52
52
|
|
|
@@ -56,7 +56,7 @@ const make = Effect.fnUntraced(function*(
|
|
|
56
56
|
*/
|
|
57
57
|
export const layer = (
|
|
58
58
|
options?: IoRedis.RedisOptions | undefined
|
|
59
|
-
): Layer.Layer<Redis.Redis | NodeRedis> => Layer.
|
|
59
|
+
): Layer.Layer<Redis.Redis | NodeRedis> => Layer.effectContext(make(options))
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* @since 1.0.0
|
|
@@ -67,7 +67,7 @@ export const layerConfig: (
|
|
|
67
67
|
) => Layer.Layer<Redis.Redis | NodeRedis, Config.ConfigError> = (
|
|
68
68
|
options: Config.Wrap<IoRedis.RedisOptions>
|
|
69
69
|
): Layer.Layer<Redis.Redis | NodeRedis, Config.ConfigError> =>
|
|
70
|
-
Layer.
|
|
70
|
+
Layer.effectContext(
|
|
71
71
|
Config.unwrap(options).asEffect().pipe(
|
|
72
72
|
Effect.flatMap(make)
|
|
73
73
|
)
|
package/src/NodeRuntime.ts
CHANGED
|
@@ -20,7 +20,6 @@ import type * as Runtime from "effect/Runtime"
|
|
|
20
20
|
*
|
|
21
21
|
* An optional object that can include:
|
|
22
22
|
* - `disableErrorReporting`: Turn off automatic error logging.
|
|
23
|
-
* - `disablePrettyLogger`: Avoid adding the pretty logger.
|
|
24
23
|
* - `teardown`: Provide custom finalization logic.
|
|
25
24
|
*
|
|
26
25
|
* **When to Use**
|
|
@@ -48,7 +47,6 @@ export const runMain: {
|
|
|
48
47
|
*
|
|
49
48
|
* An optional object that can include:
|
|
50
49
|
* - `disableErrorReporting`: Turn off automatic error logging.
|
|
51
|
-
* - `disablePrettyLogger`: Avoid adding the pretty logger.
|
|
52
50
|
* - `teardown`: Provide custom finalization logic.
|
|
53
51
|
*
|
|
54
52
|
* **When to Use**
|
|
@@ -81,7 +79,6 @@ export const runMain: {
|
|
|
81
79
|
*
|
|
82
80
|
* An optional object that can include:
|
|
83
81
|
* - `disableErrorReporting`: Turn off automatic error logging.
|
|
84
|
-
* - `disablePrettyLogger`: Avoid adding the pretty logger.
|
|
85
82
|
* - `teardown`: Provide custom finalization logic.
|
|
86
83
|
*
|
|
87
84
|
* **When to Use**
|
package/src/NodeSocket.ts
CHANGED
|
@@ -26,6 +26,16 @@ export const layerWebSocketConstructor: Layer.Layer<
|
|
|
26
26
|
return (url, protocols) => new WS.WebSocket(url, protocols) as unknown as globalThis.WebSocket
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @since 1.0.0
|
|
31
|
+
* @category layers
|
|
32
|
+
*/
|
|
33
|
+
export const layerWebSocketConstructorWS: Layer.Layer<
|
|
34
|
+
Socket.WebSocketConstructor
|
|
35
|
+
> = Layer.succeed(Socket.WebSocketConstructor)(
|
|
36
|
+
(url, protocols) => new WS.WebSocket(url, protocols) as unknown as globalThis.WebSocket
|
|
37
|
+
)
|
|
38
|
+
|
|
29
39
|
/**
|
|
30
40
|
* @since 1.0.0
|
|
31
41
|
* @category layers
|
|
@@ -34,7 +44,7 @@ export const layerWebSocket: (
|
|
|
34
44
|
url: string | Effect.Effect<string>,
|
|
35
45
|
options?: {
|
|
36
46
|
readonly closeCodeIsError?: ((code: number) => boolean) | undefined
|
|
37
|
-
readonly openTimeout?: Duration.
|
|
47
|
+
readonly openTimeout?: Duration.Input | undefined
|
|
38
48
|
readonly protocols?: string | Array<string> | undefined
|
|
39
49
|
} | undefined
|
|
40
50
|
) => Layer.Layer<Socket.Socket, never, never> = flow(
|
package/src/NodeWorkerRunner.ts
CHANGED
|
@@ -36,7 +36,7 @@ export const layer: Layer.Layer<WorkerRunner.WorkerRunnerPlatform> = Layer.succe
|
|
|
36
36
|
Effect.scopedWith(Effect.fnUntraced(function*(scope) {
|
|
37
37
|
const closeLatch = Deferred.makeUnsafe<void, WorkerError>()
|
|
38
38
|
const trackFiber = Fiber.runIn(scope)
|
|
39
|
-
const services = yield* Effect.
|
|
39
|
+
const services = yield* Effect.context<R>()
|
|
40
40
|
const runFork = Effect.runForkWith(services)
|
|
41
41
|
const onExit = (exit: Exit.Exit<any, E>) => {
|
|
42
42
|
if (exit._tag === "Failure" && !Cause.hasInterruptsOnly(exit.cause)) {
|