@effect/platform-node-shared 4.0.0-beta.8 → 4.0.0-beta.80
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/NodeChildProcessSpawner.d.ts +19 -5
- package/dist/NodeChildProcessSpawner.d.ts.map +1 -1
- package/dist/NodeChildProcessSpawner.js +77 -18
- package/dist/NodeChildProcessSpawner.js.map +1 -1
- package/dist/NodeClusterSocket.d.ts +10 -4
- package/dist/NodeClusterSocket.d.ts.map +1 -1
- package/dist/NodeClusterSocket.js +22 -8
- package/dist/NodeClusterSocket.js.map +1 -1
- package/dist/NodeCrypto.d.ts +27 -0
- package/dist/NodeCrypto.d.ts.map +1 -0
- package/dist/NodeCrypto.js +55 -0
- package/dist/NodeCrypto.js.map +1 -0
- package/dist/NodeFileSystem.d.ts +5 -2
- package/dist/NodeFileSystem.d.ts.map +1 -1
- package/dist/NodeFileSystem.js +33 -26
- package/dist/NodeFileSystem.js.map +1 -1
- package/dist/NodePath.d.ts +15 -6
- package/dist/NodePath.d.ts.map +1 -1
- package/dist/NodePath.js +23 -7
- package/dist/NodePath.js.map +1 -1
- package/dist/NodeRuntime.d.ts +26 -7
- package/dist/NodeRuntime.d.ts.map +1 -1
- package/dist/NodeRuntime.js +8 -8
- package/dist/NodeRuntime.js.map +1 -1
- package/dist/NodeSink.d.ts +33 -4
- package/dist/NodeSink.d.ts.map +1 -1
- package/dist/NodeSink.js +31 -4
- package/dist/NodeSink.js.map +1 -1
- package/dist/NodeSocket.d.ts +41 -10
- package/dist/NodeSocket.d.ts.map +1 -1
- package/dist/NodeSocket.js +39 -16
- package/dist/NodeSocket.js.map +1 -1
- package/dist/NodeSocketServer.d.ts +25 -8
- package/dist/NodeSocketServer.d.ts.map +1 -1
- package/dist/NodeSocketServer.js +29 -12
- package/dist/NodeSocketServer.js.map +1 -1
- package/dist/NodeStdio.d.ts +6 -5
- package/dist/NodeStdio.d.ts.map +1 -1
- package/dist/NodeStdio.js +23 -7
- package/dist/NodeStdio.js.map +1 -1
- package/dist/NodeStream.d.ts +76 -20
- package/dist/NodeStream.d.ts.map +1 -1
- package/dist/NodeStream.js +68 -23
- package/dist/NodeStream.js.map +1 -1
- package/dist/NodeTerminal.d.ts +9 -2
- package/dist/NodeTerminal.d.ts.map +1 -1
- package/dist/NodeTerminal.js +13 -3
- package/dist/NodeTerminal.js.map +1 -1
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/package.json +7 -6
- package/src/NodeChildProcessSpawner.ts +117 -29
- package/src/NodeClusterSocket.ts +22 -8
- package/src/NodeCrypto.ts +60 -0
- package/src/NodeFileSystem.ts +40 -28
- package/src/NodePath.ts +23 -7
- package/src/NodeRuntime.ts +28 -13
- package/src/NodeSink.ts +40 -4
- package/src/NodeSocket.ts +47 -17
- package/src/NodeSocketServer.ts +39 -13
- package/src/NodeStdio.ts +41 -23
- package/src/NodeStream.ts +89 -30
- package/src/NodeTerminal.ts +22 -4
- package/src/index.ts +65 -0
package/src/NodeRuntime.ts
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Node-compatible process runner for Effect programs.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the shared `runMain` implementation used by
|
|
5
|
+
* Node-compatible platform packages. It runs one Effect as the main process
|
|
6
|
+
* fiber, interrupts that fiber on `SIGINT` or `SIGTERM`, and delegates final
|
|
7
|
+
* exit-code handling to the configured teardown.
|
|
8
|
+
*
|
|
9
|
+
* @since 4.0.0
|
|
3
10
|
*/
|
|
4
11
|
import type { Effect } from "effect/Effect"
|
|
5
12
|
import * as Runtime from "effect/Runtime"
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
15
|
+
* Runs an Effect as the Node process main program, interrupting the fiber on
|
|
16
|
+
* `SIGINT` or `SIGTERM` and invoking the configured teardown to determine the
|
|
17
|
+
* process exit code.
|
|
18
|
+
*
|
|
19
|
+
* @category running
|
|
20
|
+
* @since 4.0.0
|
|
10
21
|
*/
|
|
11
22
|
export const runMain: {
|
|
12
23
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
24
|
+
* Runs an Effect as the Node process main program, interrupting the fiber on
|
|
25
|
+
* `SIGINT` or `SIGTERM` and invoking the configured teardown to determine the
|
|
26
|
+
* process exit code.
|
|
27
|
+
*
|
|
28
|
+
* @category running
|
|
29
|
+
* @since 4.0.0
|
|
15
30
|
*/
|
|
16
31
|
(
|
|
17
32
|
options?: {
|
|
@@ -20,8 +35,12 @@ export const runMain: {
|
|
|
20
35
|
}
|
|
21
36
|
): <E, A>(effect: Effect<A, E>) => void
|
|
22
37
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
38
|
+
* Runs an Effect as the Node process main program, interrupting the fiber on
|
|
39
|
+
* `SIGINT` or `SIGTERM` and invoking the configured teardown to determine the
|
|
40
|
+
* process exit code.
|
|
41
|
+
*
|
|
42
|
+
* @category running
|
|
43
|
+
* @since 4.0.0
|
|
25
44
|
*/
|
|
26
45
|
<E, A>(
|
|
27
46
|
effect: Effect<A, E>,
|
|
@@ -37,10 +56,8 @@ export const runMain: {
|
|
|
37
56
|
let receivedSignal = false
|
|
38
57
|
|
|
39
58
|
fiber.addObserver((exit) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
process.removeListener("SIGTERM", onSigint)
|
|
43
|
-
}
|
|
59
|
+
process.removeListener("SIGINT", onSigint)
|
|
60
|
+
process.removeListener("SIGTERM", onSigint)
|
|
44
61
|
teardown(exit, (code) => {
|
|
45
62
|
if (receivedSignal || code !== 0) {
|
|
46
63
|
process.exit(code)
|
|
@@ -50,8 +67,6 @@ export const runMain: {
|
|
|
50
67
|
|
|
51
68
|
function onSigint() {
|
|
52
69
|
receivedSignal = true
|
|
53
|
-
process.removeListener("SIGINT", onSigint)
|
|
54
|
-
process.removeListener("SIGTERM", onSigint)
|
|
55
70
|
fiber.interruptUnsafe(fiber.id)
|
|
56
71
|
}
|
|
57
72
|
|
package/src/NodeSink.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Sink adapters for writing Effect chunks into Node writable streams.
|
|
3
|
+
*
|
|
4
|
+
* `fromWritable` creates a `Sink`, `fromWritableChannel` creates a lower-level
|
|
5
|
+
* `Channel`, and `pullIntoWritable` writes from an existing pull loop. All
|
|
6
|
+
* three adapters respect writable-stream backpressure, map writable errors with
|
|
7
|
+
* the supplied `onError` function, and can end the writable when the upstream
|
|
8
|
+
* data is done.
|
|
9
|
+
*
|
|
10
|
+
* @since 4.0.0
|
|
3
11
|
*/
|
|
4
12
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
5
13
|
import * as Cause from "effect/Cause"
|
|
@@ -11,8 +19,12 @@ import * as Sink from "effect/Sink"
|
|
|
11
19
|
import type { Writable } from "node:stream"
|
|
12
20
|
|
|
13
21
|
/**
|
|
22
|
+
* Creates a `Sink` that writes chunks to a Node writable stream, respecting
|
|
23
|
+
* backpressure, mapping writable errors with `onError`, and ending the stream
|
|
24
|
+
* on completion unless `endOnDone` is `false`.
|
|
25
|
+
*
|
|
14
26
|
* @category constructors
|
|
15
|
-
* @since
|
|
27
|
+
* @since 4.0.0
|
|
16
28
|
*/
|
|
17
29
|
export const fromWritable = <E, A = Uint8Array | string>(
|
|
18
30
|
options: {
|
|
@@ -25,8 +37,12 @@ export const fromWritable = <E, A = Uint8Array | string>(
|
|
|
25
37
|
Sink.fromChannel(Channel.mapDone(fromWritableChannel<never, E, A>(options), (_) => [_]))
|
|
26
38
|
|
|
27
39
|
/**
|
|
40
|
+
* Creates a `Channel` that pulls chunks from upstream and writes them to a
|
|
41
|
+
* Node writable stream, respecting backpressure and optionally ending the
|
|
42
|
+
* writable when upstream is done.
|
|
43
|
+
*
|
|
28
44
|
* @category constructors
|
|
29
|
-
* @since
|
|
45
|
+
* @since 4.0.0
|
|
30
46
|
*/
|
|
31
47
|
export const fromWritableChannel = <IE, E, A = Uint8Array | string>(
|
|
32
48
|
options: {
|
|
@@ -42,7 +58,20 @@ export const fromWritableChannel = <IE, E, A = Uint8Array | string>(
|
|
|
42
58
|
})
|
|
43
59
|
|
|
44
60
|
/**
|
|
45
|
-
*
|
|
61
|
+
* Writes Effect chunks into a Node writable stream.
|
|
62
|
+
*
|
|
63
|
+
* **When to use**
|
|
64
|
+
*
|
|
65
|
+
* Use to implement custom Node stream adapters that already have an upstream
|
|
66
|
+
* pull and need direct control over a writable stream.
|
|
67
|
+
*
|
|
68
|
+
* **Details**
|
|
69
|
+
*
|
|
70
|
+
* The loop waits for `drain` when needed, fails on writable errors, and ends
|
|
71
|
+
* the writable on upstream completion unless `endOnDone` is `false`.
|
|
72
|
+
*
|
|
73
|
+
* @category converting
|
|
74
|
+
* @since 4.0.0
|
|
46
75
|
*/
|
|
47
76
|
export const pullIntoWritable = <A, IE, E>(options: {
|
|
48
77
|
readonly pull: Pull.Pull<NonEmptyReadonlyArray<A>, IE, unknown>
|
|
@@ -66,6 +95,13 @@ export const pullIntoWritable = <A, IE, E>(options: {
|
|
|
66
95
|
})
|
|
67
96
|
}),
|
|
68
97
|
Effect.forever({ disableYield: true }),
|
|
98
|
+
Effect.raceFirst(Effect.callback<never, E>((resume) => {
|
|
99
|
+
const onError = (error: unknown) => resume(Effect.fail(options.onError(error)))
|
|
100
|
+
options.writable.once("error", onError)
|
|
101
|
+
return Effect.sync(() => {
|
|
102
|
+
options.writable.off("error", onError)
|
|
103
|
+
})
|
|
104
|
+
})),
|
|
69
105
|
options.endOnDone !== false ?
|
|
70
106
|
Pull.catchDone((_) => {
|
|
71
107
|
if ("closed" in options.writable && options.writable.closed) {
|
package/src/NodeSocket.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Node socket adapters for Effect sockets.
|
|
3
|
+
*
|
|
4
|
+
* This module opens `node:net` connections or wraps existing Node `Duplex`
|
|
5
|
+
* streams and presents them as `Socket.Socket` values, socket channels, or
|
|
6
|
+
* layers. It also exposes the current underlying `NetSocket` service for code
|
|
7
|
+
* running inside a socket handler and re-exports the `ws` package namespace.
|
|
8
|
+
*
|
|
9
|
+
* @since 4.0.0
|
|
3
10
|
*/
|
|
4
11
|
import type { Array } from "effect"
|
|
5
12
|
import * as Channel from "effect/Channel"
|
|
13
|
+
import * as Context from "effect/Context"
|
|
6
14
|
import * as Deferred from "effect/Deferred"
|
|
7
15
|
import type * as Duration from "effect/Duration"
|
|
8
16
|
import * as Effect from "effect/Effect"
|
|
@@ -12,28 +20,41 @@ import { identity } from "effect/Function"
|
|
|
12
20
|
import * as Latch from "effect/Latch"
|
|
13
21
|
import * as Layer from "effect/Layer"
|
|
14
22
|
import * as Scope from "effect/Scope"
|
|
15
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
16
23
|
import * as Socket from "effect/unstable/socket/Socket"
|
|
17
24
|
import * as Net from "node:net"
|
|
18
25
|
import type { Duplex } from "node:stream"
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
|
-
* @since 1.0.0
|
|
22
28
|
* @category re-exports
|
|
29
|
+
* @since 4.0.0
|
|
23
30
|
*/
|
|
24
31
|
export * as NodeWS from "ws"
|
|
25
32
|
|
|
26
33
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
34
|
+
* Service tag for the underlying Node `net.Socket` associated with the current
|
|
35
|
+
* socket connection.
|
|
36
|
+
*
|
|
37
|
+
* @category services
|
|
38
|
+
* @since 4.0.0
|
|
29
39
|
*/
|
|
30
|
-
export class NetSocket extends
|
|
40
|
+
export class NetSocket extends Context.Service<NetSocket, Net.Socket>()(
|
|
31
41
|
"@effect/platform-node/NodeSocket/NetSocket"
|
|
32
42
|
) {}
|
|
33
43
|
|
|
34
44
|
/**
|
|
35
|
-
*
|
|
45
|
+
* Opens a Node TCP connection as an Effect socket.
|
|
46
|
+
*
|
|
47
|
+
* **When to use**
|
|
48
|
+
*
|
|
49
|
+
* Use to create a scoped `Socket.Socket` from Node `net.createConnection`.
|
|
50
|
+
*
|
|
51
|
+
* **Details**
|
|
52
|
+
*
|
|
53
|
+
* Supports `openTimeout` and closes or destroys the underlying socket when the
|
|
54
|
+
* enclosing scope is finalized.
|
|
55
|
+
*
|
|
36
56
|
* @category constructors
|
|
57
|
+
* @since 4.0.0
|
|
37
58
|
*/
|
|
38
59
|
export const makeNet = (
|
|
39
60
|
options: Net.NetConnectOpts & {
|
|
@@ -41,11 +62,11 @@ export const makeNet = (
|
|
|
41
62
|
}
|
|
42
63
|
): Effect.Effect<Socket.Socket> =>
|
|
43
64
|
fromDuplex(
|
|
44
|
-
Effect.
|
|
65
|
+
Effect.contextWith((context: Context.Context<Scope.Scope>) => {
|
|
45
66
|
let conn: Net.Socket | undefined
|
|
46
67
|
return Effect.flatMap(
|
|
47
68
|
Scope.addFinalizer(
|
|
48
|
-
|
|
69
|
+
Context.get(context, Scope.Scope),
|
|
49
70
|
Effect.sync(() => {
|
|
50
71
|
if (!conn) return
|
|
51
72
|
if (conn.closed === false) {
|
|
@@ -77,8 +98,12 @@ export const makeNet = (
|
|
|
77
98
|
)
|
|
78
99
|
|
|
79
100
|
/**
|
|
80
|
-
*
|
|
101
|
+
* Adapts a Node `Duplex` into a `Socket.Socket`, wiring data events to socket
|
|
102
|
+
* handlers, providing a scoped writer, and mapping open, read, write, and close
|
|
103
|
+
* failures to `SocketError`.
|
|
104
|
+
*
|
|
81
105
|
* @category constructors
|
|
106
|
+
* @since 4.0.0
|
|
82
107
|
*/
|
|
83
108
|
export const fromDuplex = <RO>(
|
|
84
109
|
open: Effect.Effect<Duplex, Socket.SocketError, RO>,
|
|
@@ -89,7 +114,7 @@ export const fromDuplex = <RO>(
|
|
|
89
114
|
Effect.withFiber<Socket.Socket, never, Exclude<RO, Scope.Scope>>((fiber) => {
|
|
90
115
|
let currentSocket: Duplex | undefined
|
|
91
116
|
const latch = Latch.makeUnsafe(false)
|
|
92
|
-
const openServices = fiber.
|
|
117
|
+
const openServices = fiber.context as Context.Context<RO>
|
|
93
118
|
|
|
94
119
|
const run = <R, E, _>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void, opts?: {
|
|
95
120
|
readonly onOpen?: Effect.Effect<void> | undefined
|
|
@@ -113,7 +138,7 @@ export const fromDuplex = <RO>(
|
|
|
113
138
|
options?.openTimeout ?
|
|
114
139
|
Effect.timeoutOrElse({
|
|
115
140
|
duration: options.openTimeout,
|
|
116
|
-
|
|
141
|
+
orElse: () =>
|
|
117
142
|
Effect.fail(
|
|
118
143
|
new Socket.SocketError({
|
|
119
144
|
reason: new Socket.SocketOpenError({ kind: "Timeout", cause: new Error("Connection timed out") })
|
|
@@ -166,7 +191,7 @@ export const fromDuplex = <RO>(
|
|
|
166
191
|
)
|
|
167
192
|
}
|
|
168
193
|
})).pipe(
|
|
169
|
-
Effect.
|
|
194
|
+
Effect.updateContext((input: Context.Context<R>) => Context.merge(openServices, input)),
|
|
170
195
|
Effect.onExit(() =>
|
|
171
196
|
Effect.sync(() => {
|
|
172
197
|
latch.closeUnsafe()
|
|
@@ -204,8 +229,7 @@ export const fromDuplex = <RO>(
|
|
|
204
229
|
})
|
|
205
230
|
)
|
|
206
231
|
|
|
207
|
-
return Effect.succeed(Socket.
|
|
208
|
-
[Socket.TypeId]: Socket.TypeId,
|
|
232
|
+
return Effect.succeed(Socket.make({
|
|
209
233
|
run,
|
|
210
234
|
runRaw: run,
|
|
211
235
|
writer
|
|
@@ -213,8 +237,11 @@ export const fromDuplex = <RO>(
|
|
|
213
237
|
})
|
|
214
238
|
|
|
215
239
|
/**
|
|
216
|
-
*
|
|
240
|
+
* Creates a `Channel` over a TCP socket, reading arrays of `Uint8Array`
|
|
241
|
+
* chunks and writing arrays of bytes, strings, or socket close events.
|
|
242
|
+
*
|
|
217
243
|
* @category constructors
|
|
244
|
+
* @since 4.0.0
|
|
218
245
|
*/
|
|
219
246
|
export const makeNetChannel = <IE = never>(
|
|
220
247
|
options: Net.NetConnectOpts
|
|
@@ -230,8 +257,11 @@ export const makeNetChannel = <IE = never>(
|
|
|
230
257
|
)
|
|
231
258
|
|
|
232
259
|
/**
|
|
233
|
-
*
|
|
260
|
+
* Provides a `Socket.Socket` by opening a TCP connection with the supplied
|
|
261
|
+
* Node `net` connection options.
|
|
262
|
+
*
|
|
234
263
|
* @category layers
|
|
264
|
+
* @since 4.0.0
|
|
235
265
|
*/
|
|
236
266
|
export const layerNet: (options: Net.NetConnectOpts) => Layer.Layer<
|
|
237
267
|
Socket.Socket,
|
package/src/NodeSocketServer.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Node socket server adapters for Effect's unstable socket server API.
|
|
3
|
+
*
|
|
4
|
+
* This module turns `node:net` TCP or Unix-domain servers and `ws` WebSocket
|
|
5
|
+
* servers into scoped `SocketServer.SocketServer` services. Use the TCP
|
|
6
|
+
* constructors when handlers should receive a `Socket.Socket` backed by a Node
|
|
7
|
+
* `net.Socket`; use the WebSocket constructors when handlers should receive a
|
|
8
|
+
* `Socket.Socket` backed by `ws` and have access to the per-connection
|
|
9
|
+
* WebSocket and `IncomingMessage` services.
|
|
10
|
+
*
|
|
11
|
+
* @since 4.0.0
|
|
3
12
|
*/
|
|
4
13
|
import type { Cause } from "effect/Cause"
|
|
14
|
+
import * as Context from "effect/Context"
|
|
5
15
|
import * as Deferred from "effect/Deferred"
|
|
6
16
|
import * as Effect from "effect/Effect"
|
|
7
17
|
import * as Exit from "effect/Exit"
|
|
@@ -11,7 +21,6 @@ import * as Function from "effect/Function"
|
|
|
11
21
|
import * as Layer from "effect/Layer"
|
|
12
22
|
import * as References from "effect/References"
|
|
13
23
|
import * as Scope from "effect/Scope"
|
|
14
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
15
24
|
import * as Socket from "effect/unstable/socket/Socket"
|
|
16
25
|
import * as SocketServer from "effect/unstable/socket/SocketServer"
|
|
17
26
|
import type * as Http from "node:http"
|
|
@@ -20,17 +29,24 @@ import * as NodeSocket from "./NodeSocket.ts"
|
|
|
20
29
|
import { NodeWS } from "./NodeSocket.ts"
|
|
21
30
|
|
|
22
31
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
32
|
+
* Service tag for the Node `IncomingMessage` associated with the current
|
|
33
|
+
* WebSocket server connection.
|
|
34
|
+
*
|
|
35
|
+
* @category services
|
|
36
|
+
* @since 4.0.0
|
|
25
37
|
*/
|
|
26
|
-
export class IncomingMessage extends
|
|
38
|
+
export class IncomingMessage extends Context.Service<
|
|
27
39
|
IncomingMessage,
|
|
28
40
|
Http.IncomingMessage
|
|
29
41
|
>()("@effect/platform-node-shared/NodeSocketServer/IncomingMessage") {}
|
|
30
42
|
|
|
31
43
|
/**
|
|
32
|
-
*
|
|
44
|
+
* Creates a scoped TCP `SocketServer` from a Node `net.Server`, starts
|
|
45
|
+
* listening with the supplied options, queues pending connections until `run`
|
|
46
|
+
* is called, and closes the server when the scope ends.
|
|
47
|
+
*
|
|
33
48
|
* @category constructors
|
|
49
|
+
* @since 4.0.0
|
|
34
50
|
*/
|
|
35
51
|
export const make = Effect.fnUntraced(function*(
|
|
36
52
|
options: Net.ServerOpts & Net.ListenOptions
|
|
@@ -69,7 +85,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
69
85
|
|
|
70
86
|
const run = Effect.fnUntraced(function*<R, E, _>(handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>) {
|
|
71
87
|
const scope = yield* Scope.make()
|
|
72
|
-
const services =
|
|
88
|
+
const services = Context.omit(Scope.Scope)(yield* Effect.context<R>()) as Context.Context<R>
|
|
73
89
|
const trackFiber = Fiber.runIn(scope)
|
|
74
90
|
const prevOnConnection = onConnection
|
|
75
91
|
onConnection = function(conn: Net.Socket) {
|
|
@@ -109,7 +125,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
109
125
|
),
|
|
110
126
|
Effect.flatMap(handler),
|
|
111
127
|
Effect.catchCause(reportUnhandledError),
|
|
112
|
-
Effect.runForkWith(
|
|
128
|
+
Effect.runForkWith(Context.add(services, NodeSocket.NetSocket, conn)),
|
|
113
129
|
trackFiber
|
|
114
130
|
)
|
|
115
131
|
}
|
|
@@ -144,8 +160,11 @@ export const make = Effect.fnUntraced(function*(
|
|
|
144
160
|
})
|
|
145
161
|
|
|
146
162
|
/**
|
|
147
|
-
*
|
|
163
|
+
* Provides a TCP `SocketServer` by creating and managing a scoped Node
|
|
164
|
+
* `net.Server` with the supplied server and listen options.
|
|
165
|
+
*
|
|
148
166
|
* @category layers
|
|
167
|
+
* @since 4.0.0
|
|
149
168
|
*/
|
|
150
169
|
export const layer: (
|
|
151
170
|
options: Net.ServerOpts & Net.ListenOptions
|
|
@@ -155,8 +174,12 @@ export const layer: (
|
|
|
155
174
|
> = Function.flow(make, Layer.effect(SocketServer.SocketServer))
|
|
156
175
|
|
|
157
176
|
/**
|
|
158
|
-
*
|
|
177
|
+
* Creates a scoped WebSocket `SocketServer` backed by the `ws` package,
|
|
178
|
+
* providing the WebSocket and its Node `IncomingMessage` to connection
|
|
179
|
+
* handlers and closing the server when the scope ends.
|
|
180
|
+
*
|
|
159
181
|
* @category constructors
|
|
182
|
+
* @since 4.0.0
|
|
160
183
|
*/
|
|
161
184
|
export const makeWebSocket: (
|
|
162
185
|
options: NodeWS.ServerOptions<typeof NodeWS.WebSocket, typeof Http.IncomingMessage>
|
|
@@ -202,7 +225,7 @@ export const makeWebSocket: (
|
|
|
202
225
|
|
|
203
226
|
const run = Effect.fnUntraced(function*<R, E, _>(handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>) {
|
|
204
227
|
const scope = yield* Scope.make()
|
|
205
|
-
const services =
|
|
228
|
+
const services = Context.omit(Scope.Scope)(yield* Effect.context<R>()) as Context.Context<R>
|
|
206
229
|
const trackFiber = Fiber.runIn(scope)
|
|
207
230
|
const prevOnConnection = onConnection
|
|
208
231
|
onConnection = function(conn: globalThis.WebSocket, req: Http.IncomingMessage) {
|
|
@@ -221,7 +244,7 @@ export const makeWebSocket: (
|
|
|
221
244
|
),
|
|
222
245
|
Effect.flatMap(handler),
|
|
223
246
|
Effect.catchCause(reportUnhandledError),
|
|
224
|
-
Effect.runForkWith(
|
|
247
|
+
Effect.runForkWith(Context.makeUnsafe(map)),
|
|
225
248
|
trackFiber
|
|
226
249
|
)
|
|
227
250
|
}
|
|
@@ -255,8 +278,11 @@ export const makeWebSocket: (
|
|
|
255
278
|
})
|
|
256
279
|
|
|
257
280
|
/**
|
|
258
|
-
*
|
|
281
|
+
* Provides a WebSocket `SocketServer` backed by the `ws` package and managed
|
|
282
|
+
* with the supplied server options.
|
|
283
|
+
*
|
|
259
284
|
* @category layers
|
|
285
|
+
* @since 4.0.0
|
|
260
286
|
*/
|
|
261
287
|
export const layerWebSocket: (
|
|
262
288
|
options: NodeSocket.NodeWS.ServerOptions<typeof NodeSocket.NodeWS.WebSocket, typeof Http.IncomingMessage>
|
package/src/NodeStdio.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared Node.js implementation of the Effect `Stdio` service.
|
|
3
|
+
*
|
|
4
|
+
* `NodeStdio` provides {@link Stdio.Stdio} from the current Node process. The
|
|
5
|
+
* exported {@link layer} reads command-line arguments from `process.argv`,
|
|
6
|
+
* consumes input from `process.stdin`, and writes normal and error output to
|
|
7
|
+
* `process.stdout` and `process.stderr`. Standard input remains open, and
|
|
8
|
+
* standard output and error output are not ended unless requested.
|
|
9
|
+
*
|
|
10
|
+
* @since 4.0.0
|
|
3
11
|
*/
|
|
12
|
+
import * as Effect from "effect/Effect"
|
|
4
13
|
import * as Layer from "effect/Layer"
|
|
5
14
|
import { systemError } from "effect/PlatformError"
|
|
6
15
|
import * as Stdio from "effect/Stdio"
|
|
@@ -8,32 +17,41 @@ import { fromWritable } from "./NodeSink.ts"
|
|
|
8
17
|
import { fromReadable } from "./NodeStream.ts"
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
20
|
+
* Provides `Stdio` from `process.argv`, `process.stdin`, `process.stdout`,
|
|
21
|
+
* and `process.stderr`; stdin remains open and stdout/stderr are not ended by
|
|
22
|
+
* default.
|
|
23
|
+
*
|
|
24
|
+
* @category layers
|
|
25
|
+
* @since 4.0.0
|
|
13
26
|
*/
|
|
14
27
|
export const layer: Layer.Layer<Stdio.Stdio> = Layer.succeed(
|
|
15
28
|
Stdio.Stdio,
|
|
16
29
|
Stdio.make({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
args: Effect.sync(() => process.argv.slice(2)),
|
|
31
|
+
stdout: (options) =>
|
|
32
|
+
fromWritable({
|
|
33
|
+
evaluate: () => process.stdout,
|
|
34
|
+
onError: (cause) =>
|
|
35
|
+
systemError({
|
|
36
|
+
module: "Stdio",
|
|
37
|
+
method: "stdout",
|
|
38
|
+
_tag: "Unknown",
|
|
39
|
+
cause
|
|
40
|
+
}),
|
|
41
|
+
endOnDone: options?.endOnDone ?? false
|
|
42
|
+
}),
|
|
43
|
+
stderr: (options) =>
|
|
44
|
+
fromWritable({
|
|
45
|
+
evaluate: () => process.stderr,
|
|
46
|
+
onError: (cause) =>
|
|
47
|
+
systemError({
|
|
48
|
+
module: "Stdio",
|
|
49
|
+
method: "stderr",
|
|
50
|
+
_tag: "Unknown",
|
|
51
|
+
cause
|
|
52
|
+
}),
|
|
53
|
+
endOnDone: options?.endOnDone ?? false
|
|
54
|
+
}),
|
|
37
55
|
stdin: fromReadable({
|
|
38
56
|
evaluate: () => process.stdin,
|
|
39
57
|
onError: (cause) =>
|