@effect/platform-node-shared 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/NodeChildProcessSpawner.d.ts +3 -3
- package/dist/NodeChildProcessSpawner.d.ts.map +1 -1
- package/dist/NodeChildProcessSpawner.js +76 -17
- 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 +33 -8
- package/dist/NodeClusterSocket.js.map +1 -1
- package/dist/NodeCrypto.d.ts +22 -0
- package/dist/NodeCrypto.d.ts.map +1 -0
- package/dist/NodeCrypto.js +50 -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 +43 -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 +30 -7
- package/dist/NodePath.js.map +1 -1
- package/dist/NodeRuntime.d.ts +36 -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 +34 -4
- package/dist/NodeSink.d.ts.map +1 -1
- package/dist/NodeSink.js +23 -4
- package/dist/NodeSink.js.map +1 -1
- package/dist/NodeSocket.d.ts +40 -9
- package/dist/NodeSocket.d.ts.map +1 -1
- package/dist/NodeSocket.js +31 -15
- package/dist/NodeSocket.js.map +1 -1
- package/dist/NodeSocketServer.d.ts +24 -7
- package/dist/NodeSocketServer.d.ts.map +1 -1
- package/dist/NodeSocketServer.js +28 -11
- 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 +31 -7
- package/dist/NodeStdio.js.map +1 -1
- package/dist/NodeStream.d.ts +84 -20
- package/dist/NodeStream.d.ts.map +1 -1
- package/dist/NodeStream.js +76 -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 +220 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +221 -0
- package/dist/index.js.map +1 -0
- package/package.json +7 -6
- package/src/NodeChildProcessSpawner.ts +101 -27
- package/src/NodeClusterSocket.ts +33 -8
- package/src/NodeCrypto.ts +55 -0
- package/src/NodeFileSystem.ts +50 -28
- package/src/NodePath.ts +30 -7
- package/src/NodeRuntime.ts +38 -13
- package/src/NodeSink.ts +41 -4
- package/src/NodeSocket.ts +46 -16
- package/src/NodeSocketServer.ts +46 -12
- package/src/NodeStdio.ts +49 -23
- package/src/NodeStream.ts +97 -30
- package/src/NodeTerminal.ts +31 -4
- package/src/index.ts +233 -0
package/src/NodeSink.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Sink adapters for writing Effect stream chunks into Node writable streams.
|
|
3
|
+
*
|
|
4
|
+
* This module is used at the boundary where Effect `Stream`s or `Channel`s need
|
|
5
|
+
* to push data into Node's writable side: file streams, HTTP request or
|
|
6
|
+
* response bodies, process stdio, sockets, and transform inputs such as
|
|
7
|
+
* compression or encryption streams. It exposes both a `Sink` constructor for
|
|
8
|
+
* ordinary stream pipelines and lower-level `Channel` and pull helpers used by
|
|
9
|
+
* other Node stream adapters.
|
|
10
|
+
*
|
|
11
|
+
* The implementation follows Node writable semantics. Chunks are written in
|
|
12
|
+
* order; when `write` returns `false`, pulling pauses until `drain` so upstream
|
|
13
|
+
* producers do not overrun the writable buffer. Writable `error` events are
|
|
14
|
+
* mapped through `onError`, and the writable is ended and awaited via `finish`
|
|
15
|
+
* when upstream completes unless `endOnDone` is `false`. Use `endOnDone: false`
|
|
16
|
+
* for externally owned or long-lived writables, and make sure `onError` keeps
|
|
17
|
+
* Node's untyped errors meaningful for the calling Effect workflow.
|
|
18
|
+
*
|
|
19
|
+
* @since 4.0.0
|
|
3
20
|
*/
|
|
4
21
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
5
22
|
import * as Cause from "effect/Cause"
|
|
@@ -11,8 +28,12 @@ import * as Sink from "effect/Sink"
|
|
|
11
28
|
import type { Writable } from "node:stream"
|
|
12
29
|
|
|
13
30
|
/**
|
|
31
|
+
* Creates a `Sink` that writes chunks to a Node writable stream, respecting
|
|
32
|
+
* backpressure, mapping writable errors with `onError`, and ending the stream
|
|
33
|
+
* on completion unless `endOnDone` is `false`.
|
|
34
|
+
*
|
|
14
35
|
* @category constructors
|
|
15
|
-
* @since
|
|
36
|
+
* @since 4.0.0
|
|
16
37
|
*/
|
|
17
38
|
export const fromWritable = <E, A = Uint8Array | string>(
|
|
18
39
|
options: {
|
|
@@ -25,8 +46,12 @@ export const fromWritable = <E, A = Uint8Array | string>(
|
|
|
25
46
|
Sink.fromChannel(Channel.mapDone(fromWritableChannel<never, E, A>(options), (_) => [_]))
|
|
26
47
|
|
|
27
48
|
/**
|
|
49
|
+
* Creates a `Channel` that pulls chunks from upstream and writes them to a
|
|
50
|
+
* Node writable stream, respecting backpressure and optionally ending the
|
|
51
|
+
* writable when upstream is done.
|
|
52
|
+
*
|
|
28
53
|
* @category constructors
|
|
29
|
-
* @since
|
|
54
|
+
* @since 4.0.0
|
|
30
55
|
*/
|
|
31
56
|
export const fromWritableChannel = <IE, E, A = Uint8Array | string>(
|
|
32
57
|
options: {
|
|
@@ -42,7 +67,12 @@ export const fromWritableChannel = <IE, E, A = Uint8Array | string>(
|
|
|
42
67
|
})
|
|
43
68
|
|
|
44
69
|
/**
|
|
45
|
-
*
|
|
70
|
+
* Repeatedly pulls non-empty chunks and writes them to a Node writable stream,
|
|
71
|
+
* waiting for `drain` when needed, failing on writable errors, and ending the
|
|
72
|
+
* writable on upstream completion unless disabled.
|
|
73
|
+
*
|
|
74
|
+
* @category converting
|
|
75
|
+
* @since 4.0.0
|
|
46
76
|
*/
|
|
47
77
|
export const pullIntoWritable = <A, IE, E>(options: {
|
|
48
78
|
readonly pull: Pull.Pull<NonEmptyReadonlyArray<A>, IE, unknown>
|
|
@@ -66,6 +96,13 @@ export const pullIntoWritable = <A, IE, E>(options: {
|
|
|
66
96
|
})
|
|
67
97
|
}),
|
|
68
98
|
Effect.forever({ disableYield: true }),
|
|
99
|
+
Effect.raceFirst(Effect.callback<never, E>((resume) => {
|
|
100
|
+
const onError = (error: unknown) => resume(Effect.fail(options.onError(error)))
|
|
101
|
+
options.writable.once("error", onError)
|
|
102
|
+
return Effect.sync(() => {
|
|
103
|
+
options.writable.off("error", onError)
|
|
104
|
+
})
|
|
105
|
+
})),
|
|
69
106
|
options.endOnDone !== false ?
|
|
70
107
|
Pull.catchDone((_) => {
|
|
71
108
|
if ("closed" in options.writable && options.writable.closed) {
|
package/src/NodeSocket.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared Node socket constructors for adapting `node:net` connections and
|
|
3
|
+
* other Node `Duplex` streams to Effect's `Socket.Socket` interface.
|
|
4
|
+
*
|
|
5
|
+
* Use this module when building TCP clients, Unix domain socket clients, or
|
|
6
|
+
* higher-level protocols that already expose a Node `Duplex`. Connections are
|
|
7
|
+
* scoped, so finalizers close or destroy the underlying stream, open timeouts
|
|
8
|
+
* are reported as socket open errors, and Node read, write, and close events
|
|
9
|
+
* are translated into `SocketError` values.
|
|
10
|
+
*
|
|
11
|
+
* Node sockets have a few operational details worth keeping in mind: Unix
|
|
12
|
+
* socket paths are supplied through `NetConnectOpts.path`, writes complete only
|
|
13
|
+
* after Node accepts or flushes the chunk, and abnormal close events are
|
|
14
|
+
* surfaced as close errors while normal remote ends complete the socket run.
|
|
15
|
+
*
|
|
16
|
+
* @since 4.0.0
|
|
3
17
|
*/
|
|
4
18
|
import type { Array } from "effect"
|
|
5
19
|
import * as Channel from "effect/Channel"
|
|
20
|
+
import * as Context from "effect/Context"
|
|
6
21
|
import * as Deferred from "effect/Deferred"
|
|
7
22
|
import type * as Duration from "effect/Duration"
|
|
8
23
|
import * as Effect from "effect/Effect"
|
|
@@ -12,28 +27,34 @@ import { identity } from "effect/Function"
|
|
|
12
27
|
import * as Latch from "effect/Latch"
|
|
13
28
|
import * as Layer from "effect/Layer"
|
|
14
29
|
import * as Scope from "effect/Scope"
|
|
15
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
16
30
|
import * as Socket from "effect/unstable/socket/Socket"
|
|
17
31
|
import * as Net from "node:net"
|
|
18
32
|
import type { Duplex } from "node:stream"
|
|
19
33
|
|
|
20
34
|
/**
|
|
21
|
-
* @since 1.0.0
|
|
22
35
|
* @category re-exports
|
|
36
|
+
* @since 4.0.0
|
|
23
37
|
*/
|
|
24
38
|
export * as NodeWS from "ws"
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
|
-
*
|
|
41
|
+
* Service tag for the underlying Node `net.Socket` associated with the current
|
|
42
|
+
* socket connection.
|
|
43
|
+
*
|
|
28
44
|
* @category tags
|
|
45
|
+
* @since 4.0.0
|
|
29
46
|
*/
|
|
30
|
-
export class NetSocket extends
|
|
47
|
+
export class NetSocket extends Context.Service<NetSocket, Net.Socket>()(
|
|
31
48
|
"@effect/platform-node/NodeSocket/NetSocket"
|
|
32
49
|
) {}
|
|
33
50
|
|
|
34
51
|
/**
|
|
35
|
-
*
|
|
52
|
+
* Opens a TCP connection with Node `net.createConnection` and exposes it as a
|
|
53
|
+
* `Socket.Socket`, supporting `openTimeout` and closing or destroying the
|
|
54
|
+
* socket when the 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,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared Node socket server constructors for exposing `node:net` servers and
|
|
3
|
+
* `ws` WebSocket servers as Effect `SocketServer.SocketServer` services.
|
|
4
|
+
*
|
|
5
|
+
* Use this module when implementing TCP services, Unix domain socket services,
|
|
6
|
+
* WebSocket endpoints, or higher-level protocols such as RPC transports that
|
|
7
|
+
* need to accept incoming connections through Effect's socket APIs. TCP
|
|
8
|
+
* connections are adapted through `NodeSocket.fromDuplex`, while WebSocket
|
|
9
|
+
* handlers also receive the underlying `WebSocket` and Node `IncomingMessage`
|
|
10
|
+
* in their fiber context.
|
|
11
|
+
*
|
|
12
|
+
* The server starts listening before the constructor returns, and the exported
|
|
13
|
+
* `address` is derived from the actual Node server after binding. Prefer that
|
|
14
|
+
* address when using port `0`, wildcard hosts, or Unix socket paths. Incoming
|
|
15
|
+
* connections accepted before `run` is installed are queued and then handed to
|
|
16
|
+
* the handler, each `run` call owns the scope for its connection fibers, and
|
|
17
|
+
* the enclosing scope closes the underlying Node server.
|
|
18
|
+
*
|
|
19
|
+
* @since 4.0.0
|
|
3
20
|
*/
|
|
4
21
|
import type { Cause } from "effect/Cause"
|
|
22
|
+
import * as Context from "effect/Context"
|
|
5
23
|
import * as Deferred from "effect/Deferred"
|
|
6
24
|
import * as Effect from "effect/Effect"
|
|
7
25
|
import * as Exit from "effect/Exit"
|
|
@@ -11,7 +29,6 @@ import * as Function from "effect/Function"
|
|
|
11
29
|
import * as Layer from "effect/Layer"
|
|
12
30
|
import * as References from "effect/References"
|
|
13
31
|
import * as Scope from "effect/Scope"
|
|
14
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
15
32
|
import * as Socket from "effect/unstable/socket/Socket"
|
|
16
33
|
import * as SocketServer from "effect/unstable/socket/SocketServer"
|
|
17
34
|
import type * as Http from "node:http"
|
|
@@ -20,17 +37,24 @@ import * as NodeSocket from "./NodeSocket.ts"
|
|
|
20
37
|
import { NodeWS } from "./NodeSocket.ts"
|
|
21
38
|
|
|
22
39
|
/**
|
|
23
|
-
*
|
|
40
|
+
* Service tag for the Node `IncomingMessage` associated with the current
|
|
41
|
+
* WebSocket server connection.
|
|
42
|
+
*
|
|
24
43
|
* @category tags
|
|
44
|
+
* @since 4.0.0
|
|
25
45
|
*/
|
|
26
|
-
export class IncomingMessage extends
|
|
46
|
+
export class IncomingMessage extends Context.Service<
|
|
27
47
|
IncomingMessage,
|
|
28
48
|
Http.IncomingMessage
|
|
29
49
|
>()("@effect/platform-node-shared/NodeSocketServer/IncomingMessage") {}
|
|
30
50
|
|
|
31
51
|
/**
|
|
32
|
-
*
|
|
52
|
+
* Creates a scoped TCP `SocketServer` from a Node `net.Server`, starts
|
|
53
|
+
* listening with the supplied options, queues pending connections until `run`
|
|
54
|
+
* is called, and closes the server when the scope ends.
|
|
55
|
+
*
|
|
33
56
|
* @category constructors
|
|
57
|
+
* @since 4.0.0
|
|
34
58
|
*/
|
|
35
59
|
export const make = Effect.fnUntraced(function*(
|
|
36
60
|
options: Net.ServerOpts & Net.ListenOptions
|
|
@@ -69,7 +93,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
69
93
|
|
|
70
94
|
const run = Effect.fnUntraced(function*<R, E, _>(handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>) {
|
|
71
95
|
const scope = yield* Scope.make()
|
|
72
|
-
const services =
|
|
96
|
+
const services = Context.omit(Scope.Scope)(yield* Effect.context<R>()) as Context.Context<R>
|
|
73
97
|
const trackFiber = Fiber.runIn(scope)
|
|
74
98
|
const prevOnConnection = onConnection
|
|
75
99
|
onConnection = function(conn: Net.Socket) {
|
|
@@ -109,7 +133,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
109
133
|
),
|
|
110
134
|
Effect.flatMap(handler),
|
|
111
135
|
Effect.catchCause(reportUnhandledError),
|
|
112
|
-
Effect.runForkWith(
|
|
136
|
+
Effect.runForkWith(Context.add(services, NodeSocket.NetSocket, conn)),
|
|
113
137
|
trackFiber
|
|
114
138
|
)
|
|
115
139
|
}
|
|
@@ -144,8 +168,11 @@ export const make = Effect.fnUntraced(function*(
|
|
|
144
168
|
})
|
|
145
169
|
|
|
146
170
|
/**
|
|
147
|
-
*
|
|
171
|
+
* Provides a TCP `SocketServer` by creating and managing a scoped Node
|
|
172
|
+
* `net.Server` with the supplied server and listen options.
|
|
173
|
+
*
|
|
148
174
|
* @category layers
|
|
175
|
+
* @since 4.0.0
|
|
149
176
|
*/
|
|
150
177
|
export const layer: (
|
|
151
178
|
options: Net.ServerOpts & Net.ListenOptions
|
|
@@ -155,8 +182,12 @@ export const layer: (
|
|
|
155
182
|
> = Function.flow(make, Layer.effect(SocketServer.SocketServer))
|
|
156
183
|
|
|
157
184
|
/**
|
|
158
|
-
*
|
|
185
|
+
* Creates a scoped WebSocket `SocketServer` backed by the `ws` package,
|
|
186
|
+
* providing the WebSocket and its Node `IncomingMessage` to connection
|
|
187
|
+
* handlers and closing the server when the scope ends.
|
|
188
|
+
*
|
|
159
189
|
* @category constructors
|
|
190
|
+
* @since 4.0.0
|
|
160
191
|
*/
|
|
161
192
|
export const makeWebSocket: (
|
|
162
193
|
options: NodeWS.ServerOptions<typeof NodeWS.WebSocket, typeof Http.IncomingMessage>
|
|
@@ -202,7 +233,7 @@ export const makeWebSocket: (
|
|
|
202
233
|
|
|
203
234
|
const run = Effect.fnUntraced(function*<R, E, _>(handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>) {
|
|
204
235
|
const scope = yield* Scope.make()
|
|
205
|
-
const services =
|
|
236
|
+
const services = Context.omit(Scope.Scope)(yield* Effect.context<R>()) as Context.Context<R>
|
|
206
237
|
const trackFiber = Fiber.runIn(scope)
|
|
207
238
|
const prevOnConnection = onConnection
|
|
208
239
|
onConnection = function(conn: globalThis.WebSocket, req: Http.IncomingMessage) {
|
|
@@ -221,7 +252,7 @@ export const makeWebSocket: (
|
|
|
221
252
|
),
|
|
222
253
|
Effect.flatMap(handler),
|
|
223
254
|
Effect.catchCause(reportUnhandledError),
|
|
224
|
-
Effect.runForkWith(
|
|
255
|
+
Effect.runForkWith(Context.makeUnsafe(map)),
|
|
225
256
|
trackFiber
|
|
226
257
|
)
|
|
227
258
|
}
|
|
@@ -255,8 +286,11 @@ export const makeWebSocket: (
|
|
|
255
286
|
})
|
|
256
287
|
|
|
257
288
|
/**
|
|
258
|
-
*
|
|
289
|
+
* Provides a WebSocket `SocketServer` backed by the `ws` package and managed
|
|
290
|
+
* with the supplied server options.
|
|
291
|
+
*
|
|
259
292
|
* @category layers
|
|
293
|
+
* @since 4.0.0
|
|
260
294
|
*/
|
|
261
295
|
export const layerWebSocket: (
|
|
262
296
|
options: NodeSocket.NodeWS.ServerOptions<typeof NodeSocket.NodeWS.WebSocket, typeof Http.IncomingMessage>
|
package/src/NodeStdio.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared Node.js implementation of the Effect `Stdio` service.
|
|
3
|
+
*
|
|
4
|
+
* This module builds the `Stdio` layer used by Node platform packages by
|
|
5
|
+
* wiring the service to the current process: command-line arguments come from
|
|
6
|
+
* `process.argv`, input is read from `process.stdin`, and output and error
|
|
7
|
+
* output are written to `process.stdout` and `process.stderr`. It is intended
|
|
8
|
+
* for CLIs, scripts, command runners, test harnesses, and other
|
|
9
|
+
* process-oriented programs that need standard I/O through Effect services.
|
|
10
|
+
*
|
|
11
|
+
* The process stdio streams are global resources owned by Node. This layer
|
|
12
|
+
* leaves stdin open and does not end stdout or stderr by default, avoiding
|
|
13
|
+
* accidental closure of handles other code in the process may still use. Those
|
|
14
|
+
* streams may be pipes, files, or TTYs; interactive terminal behavior such as
|
|
15
|
+
* raw mode, echo, colors, and cursor movement should be coordinated with the
|
|
16
|
+
* terminal APIs instead of assuming this layer has exclusive control.
|
|
17
|
+
*
|
|
18
|
+
* @since 4.0.0
|
|
3
19
|
*/
|
|
20
|
+
import * as Effect from "effect/Effect"
|
|
4
21
|
import * as Layer from "effect/Layer"
|
|
5
22
|
import { systemError } from "effect/PlatformError"
|
|
6
23
|
import * as Stdio from "effect/Stdio"
|
|
@@ -8,32 +25,41 @@ import { fromWritable } from "./NodeSink.ts"
|
|
|
8
25
|
import { fromReadable } from "./NodeStream.ts"
|
|
9
26
|
|
|
10
27
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
28
|
+
* Provides `Stdio` from `process.argv`, `process.stdin`, `process.stdout`,
|
|
29
|
+
* and `process.stderr`; stdin remains open and stdout/stderr are not ended by
|
|
30
|
+
* default.
|
|
31
|
+
*
|
|
32
|
+
* @category layers
|
|
33
|
+
* @since 4.0.0
|
|
13
34
|
*/
|
|
14
35
|
export const layer: Layer.Layer<Stdio.Stdio> = Layer.succeed(
|
|
15
36
|
Stdio.Stdio,
|
|
16
37
|
Stdio.make({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
args: Effect.sync(() => process.argv.slice(2)),
|
|
39
|
+
stdout: (options) =>
|
|
40
|
+
fromWritable({
|
|
41
|
+
evaluate: () => process.stdout,
|
|
42
|
+
onError: (cause) =>
|
|
43
|
+
systemError({
|
|
44
|
+
module: "Stdio",
|
|
45
|
+
method: "stdout",
|
|
46
|
+
_tag: "Unknown",
|
|
47
|
+
cause
|
|
48
|
+
}),
|
|
49
|
+
endOnDone: options?.endOnDone ?? false
|
|
50
|
+
}),
|
|
51
|
+
stderr: (options) =>
|
|
52
|
+
fromWritable({
|
|
53
|
+
evaluate: () => process.stderr,
|
|
54
|
+
onError: (cause) =>
|
|
55
|
+
systemError({
|
|
56
|
+
module: "Stdio",
|
|
57
|
+
method: "stderr",
|
|
58
|
+
_tag: "Unknown",
|
|
59
|
+
cause
|
|
60
|
+
}),
|
|
61
|
+
endOnDone: options?.endOnDone ?? false
|
|
62
|
+
}),
|
|
37
63
|
stdin: fromReadable({
|
|
38
64
|
evaluate: () => process.stdin,
|
|
39
65
|
onError: (cause) =>
|