@effect/platform-node-shared 4.0.0-beta.9 → 4.0.0-beta.90

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.
Files changed (66) hide show
  1. package/dist/NodeChildProcessSpawner.d.ts +19 -5
  2. package/dist/NodeChildProcessSpawner.d.ts.map +1 -1
  3. package/dist/NodeChildProcessSpawner.js +77 -18
  4. package/dist/NodeChildProcessSpawner.js.map +1 -1
  5. package/dist/NodeClusterSocket.d.ts +10 -4
  6. package/dist/NodeClusterSocket.d.ts.map +1 -1
  7. package/dist/NodeClusterSocket.js +22 -8
  8. package/dist/NodeClusterSocket.js.map +1 -1
  9. package/dist/NodeCrypto.d.ts +27 -0
  10. package/dist/NodeCrypto.d.ts.map +1 -0
  11. package/dist/NodeCrypto.js +55 -0
  12. package/dist/NodeCrypto.js.map +1 -0
  13. package/dist/NodeFileSystem.d.ts +5 -2
  14. package/dist/NodeFileSystem.d.ts.map +1 -1
  15. package/dist/NodeFileSystem.js +33 -26
  16. package/dist/NodeFileSystem.js.map +1 -1
  17. package/dist/NodePath.d.ts +15 -6
  18. package/dist/NodePath.d.ts.map +1 -1
  19. package/dist/NodePath.js +23 -7
  20. package/dist/NodePath.js.map +1 -1
  21. package/dist/NodeRuntime.d.ts +26 -7
  22. package/dist/NodeRuntime.d.ts.map +1 -1
  23. package/dist/NodeRuntime.js +8 -8
  24. package/dist/NodeRuntime.js.map +1 -1
  25. package/dist/NodeSink.d.ts +33 -4
  26. package/dist/NodeSink.d.ts.map +1 -1
  27. package/dist/NodeSink.js +31 -4
  28. package/dist/NodeSink.js.map +1 -1
  29. package/dist/NodeSocket.d.ts +41 -10
  30. package/dist/NodeSocket.d.ts.map +1 -1
  31. package/dist/NodeSocket.js +39 -16
  32. package/dist/NodeSocket.js.map +1 -1
  33. package/dist/NodeSocketServer.d.ts +25 -8
  34. package/dist/NodeSocketServer.d.ts.map +1 -1
  35. package/dist/NodeSocketServer.js +29 -12
  36. package/dist/NodeSocketServer.js.map +1 -1
  37. package/dist/NodeStdio.d.ts +6 -5
  38. package/dist/NodeStdio.d.ts.map +1 -1
  39. package/dist/NodeStdio.js +23 -7
  40. package/dist/NodeStdio.js.map +1 -1
  41. package/dist/NodeStream.d.ts +76 -20
  42. package/dist/NodeStream.d.ts.map +1 -1
  43. package/dist/NodeStream.js +68 -23
  44. package/dist/NodeStream.js.map +1 -1
  45. package/dist/NodeTerminal.d.ts +9 -2
  46. package/dist/NodeTerminal.d.ts.map +1 -1
  47. package/dist/NodeTerminal.js +13 -3
  48. package/dist/NodeTerminal.js.map +1 -1
  49. package/dist/index.d.ts +52 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +53 -0
  52. package/dist/index.js.map +1 -0
  53. package/package.json +7 -6
  54. package/src/NodeChildProcessSpawner.ts +117 -29
  55. package/src/NodeClusterSocket.ts +22 -8
  56. package/src/NodeCrypto.ts +60 -0
  57. package/src/NodeFileSystem.ts +40 -28
  58. package/src/NodePath.ts +23 -7
  59. package/src/NodeRuntime.ts +28 -13
  60. package/src/NodeSink.ts +40 -4
  61. package/src/NodeSocket.ts +47 -17
  62. package/src/NodeSocketServer.ts +39 -13
  63. package/src/NodeStdio.ts +41 -23
  64. package/src/NodeStream.ts +89 -30
  65. package/src/NodeTerminal.ts +22 -4
  66. package/src/index.ts +65 -0
package/src/NodeStream.ts CHANGED
@@ -1,9 +1,18 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * Adapters between Node streams and Effect streams, channels, and readables.
3
+ *
4
+ * This module is the stream boundary for Node APIs. It wraps `Readable` and
5
+ * `Duplex` values as Effect `Stream`s and `Channel`s, pipes Effect streams
6
+ * through Node duplex streams, exposes an Effect `Stream` back to Node as a
7
+ * `Readable`, and collects readable payloads into strings, array buffers, or
8
+ * `Uint8Array`s with optional byte limits.
9
+ *
10
+ * @since 4.0.0
3
11
  */
4
12
  import * as Arr from "effect/Array"
5
13
  import * as Cause from "effect/Cause"
6
14
  import * as Channel from "effect/Channel"
15
+ import * as Context from "effect/Context"
7
16
  import * as Effect from "effect/Effect"
8
17
  import * as Exit from "effect/Exit"
9
18
  import * as Fiber from "effect/Fiber"
@@ -13,15 +22,18 @@ import * as Latch from "effect/Latch"
13
22
  import * as MutableRef from "effect/MutableRef"
14
23
  import * as Pull from "effect/Pull"
15
24
  import * as Scope from "effect/Scope"
16
- import * as ServiceMap from "effect/ServiceMap"
17
25
  import * as Stream from "effect/Stream"
18
26
  import type { Duplex } from "node:stream"
19
27
  import { Readable } from "node:stream"
20
28
  import { pullIntoWritable } from "./NodeSink.ts"
21
29
 
22
30
  /**
31
+ * Converts a Node readable stream into an Effect `Stream`, reading chunks with
32
+ * an optional chunk size, mapping stream errors with `onError`, and destroying
33
+ * the readable on completion unless `closeOnDone` is `false`.
34
+ *
23
35
  * @category constructors
24
- * @since 1.0.0
36
+ * @since 4.0.0
25
37
  */
26
38
  export const fromReadable = <A = Uint8Array, E = Cause.UnknownError>(options: {
27
39
  readonly evaluate: LazyArg<Readable | NodeJS.ReadableStream>
@@ -32,8 +44,12 @@ export const fromReadable = <A = Uint8Array, E = Cause.UnknownError>(options: {
32
44
  }): Stream.Stream<A, E> => Stream.fromChannel(fromReadableChannel<A, E>(options))
33
45
 
34
46
  /**
47
+ * Creates a `Channel` that pulls chunks from a Node readable stream, mapping
48
+ * errors with `onError` and destroying the readable on completion unless
49
+ * `closeOnDone` is `false`.
50
+ *
35
51
  * @category constructors
36
- * @since 1.0.0
52
+ * @since 4.0.0
37
53
  */
38
54
  export const fromReadableChannel = <A = Uint8Array, E = Cause.UnknownError>(options: {
39
55
  readonly evaluate: LazyArg<Readable | NodeJS.ReadableStream>
@@ -52,8 +68,12 @@ export const fromReadableChannel = <A = Uint8Array, E = Cause.UnknownError>(opti
52
68
  )
53
69
 
54
70
  /**
71
+ * Creates a `Channel` over a Node `Duplex`, writing upstream chunks with
72
+ * backpressure while emitting chunks read from the duplex and optionally ending
73
+ * the writable side when upstream completes.
74
+ *
55
75
  * @category constructors
56
- * @since 1.0.0
76
+ * @since 4.0.0
57
77
  */
58
78
  export const fromDuplex = <IE, I = Uint8Array, O = Uint8Array, E = Cause.UnknownError>(
59
79
  options: {
@@ -95,13 +115,19 @@ export const fromDuplex = <IE, I = Uint8Array, O = Uint8Array, E = Cause.Unknown
95
115
  })
96
116
 
97
117
  /**
118
+ * Pipes an Effect `Stream` through a Node `Duplex`, writing the stream's
119
+ * chunks to the duplex and emitting chunks read back from it.
120
+ *
98
121
  * @category combinators
99
- * @since 1.0.0
122
+ * @since 4.0.0
100
123
  */
101
124
  export const pipeThroughDuplex: {
102
125
  /**
126
+ * Pipes an Effect `Stream` through a Node `Duplex`, writing the stream's
127
+ * chunks to the duplex and emitting chunks read back from it.
128
+ *
103
129
  * @category combinators
104
- * @since 1.0.0
130
+ * @since 4.0.0
105
131
  */
106
132
  <B = Uint8Array, E2 = Cause.UnknownError>(
107
133
  options: {
@@ -114,8 +140,11 @@ export const pipeThroughDuplex: {
114
140
  }
115
141
  ): <R, E, A>(self: Stream.Stream<A, E, R>) => Stream.Stream<B, E2 | E, R>
116
142
  /**
143
+ * Pipes an Effect `Stream` through a Node `Duplex`, writing the stream's
144
+ * chunks to the duplex and emitting chunks read back from it.
145
+ *
117
146
  * @category combinators
118
- * @since 1.0.0
147
+ * @since 4.0.0
119
148
  */
120
149
  <R, E, A, B = Uint8Array, E2 = Cause.UnknownError>(
121
150
  self: Stream.Stream<A, E, R>,
@@ -145,18 +174,27 @@ export const pipeThroughDuplex: {
145
174
  ))
146
175
 
147
176
  /**
177
+ * Pipes a stream of strings or bytes through a Node `Duplex` using default
178
+ * options and `Cause.UnknownError` for stream failures.
179
+ *
148
180
  * @category combinators
149
- * @since 1.0.0
181
+ * @since 4.0.0
150
182
  */
151
183
  export const pipeThroughSimple: {
152
184
  /**
185
+ * Pipes a stream of strings or bytes through a Node `Duplex` using default
186
+ * options and `Cause.UnknownError` for stream failures.
187
+ *
153
188
  * @category combinators
154
- * @since 1.0.0
189
+ * @since 4.0.0
155
190
  */
156
191
  (duplex: LazyArg<Duplex>): <R, E>(self: Stream.Stream<string | Uint8Array, E, R>) => Stream.Stream<Uint8Array, E | Cause.UnknownError, R>
157
192
  /**
193
+ * Pipes a stream of strings or bytes through a Node `Duplex` using default
194
+ * options and `Cause.UnknownError` for stream failures.
195
+ *
158
196
  * @category combinators
159
- * @since 1.0.0
197
+ * @since 4.0.0
160
198
  */
161
199
  <R, E>(self: Stream.Stream<string | Uint8Array, E, R>, duplex: LazyArg<Duplex>): Stream.Stream<Uint8Array, Cause.UnknownError | E, R>
162
200
  } = dual(2, <R, E>(
@@ -165,28 +203,39 @@ export const pipeThroughSimple: {
165
203
  ): Stream.Stream<Uint8Array, Cause.UnknownError | E, R> => pipeThroughDuplex(self, { evaluate: duplex }))
166
204
 
167
205
  /**
168
- * @since 1.0.0
169
- * @category conversions
206
+ * Converts an Effect `Stream` into a Node `Readable`, using the caller's
207
+ * Effect context to run the stream and destroying the readable if the stream
208
+ * fails.
209
+ *
210
+ * @category converting
211
+ * @since 4.0.0
170
212
  */
171
213
  export const toReadable = <E, R>(stream: Stream.Stream<string | Uint8Array, E, R>): Effect.Effect<Readable, never, R> =>
172
214
  Effect.map(
173
- Effect.services<R>(),
215
+ Effect.context<R>(),
174
216
  (context) => new StreamAdapter(context, stream)
175
217
  )
176
218
 
177
219
  /**
178
- * @since 1.0.0
179
- * @category conversions
220
+ * Converts a service-free Effect `Stream` into a Node `Readable` using an
221
+ * empty Effect context.
222
+ *
223
+ * @category converting
224
+ * @since 4.0.0
180
225
  */
181
226
  export const toReadableNever = <E>(stream: Stream.Stream<string | Uint8Array, E, never>): Readable =>
182
227
  new StreamAdapter(
183
- ServiceMap.empty(),
228
+ Context.empty(),
184
229
  stream
185
230
  )
186
231
 
187
232
  /**
188
- * @since 1.0.0
189
- * @category conversions
233
+ * Consumes a Node readable stream into a string using the selected encoding,
234
+ * failing through `onError` on stream errors or when `maxBytes` is exceeded
235
+ * and destroying the stream on interruption or failure.
236
+ *
237
+ * @category converting
238
+ * @since 4.0.0
190
239
  */
191
240
  export const toString = <E = Cause.UnknownError>(
192
241
  readable: LazyArg<Readable | NodeJS.ReadableStream>,
@@ -234,8 +283,12 @@ export const toString = <E = Cause.UnknownError>(
234
283
  }
235
284
 
236
285
  /**
237
- * @since 1.0.0
238
- * @category conversions
286
+ * Consumes a Node readable stream into an `ArrayBuffer`, failing through
287
+ * `onError` on stream errors or when `maxBytes` is exceeded and destroying the
288
+ * stream on interruption or failure.
289
+ *
290
+ * @category converting
291
+ * @since 4.0.0
239
292
  */
240
293
  export const toArrayBuffer = <E = Cause.UnknownError>(
241
294
  readable: LazyArg<Readable | NodeJS.ReadableStream>,
@@ -248,7 +301,7 @@ export const toArrayBuffer = <E = Cause.UnknownError>(
248
301
  const onError = options?.onError ?? defaultOnError
249
302
  return Effect.callback((resume) => {
250
303
  const stream = readable() as Readable
251
- let buffer = Buffer.alloc(0)
304
+ const buffers: Array<Uint8Array> = []
252
305
  let bytes = 0
253
306
  stream.once("error", (err) => {
254
307
  if ("closed" in stream && !stream.closed) {
@@ -257,13 +310,16 @@ export const toArrayBuffer = <E = Cause.UnknownError>(
257
310
  resume(Effect.fail(onError(err) as E))
258
311
  })
259
312
  stream.once("end", () => {
260
- if (buffer.buffer.byteLength === buffer.byteLength) {
261
- return resume(Effect.succeed(buffer.buffer))
313
+ const buffer = buffers.length === 1 ? buffers[0] : Buffer.concat(buffers)
314
+ if (buffer.byteOffset === 0 && buffer.buffer.byteLength === buffer.byteLength) {
315
+ return resume(Effect.succeed(buffer.buffer as ArrayBuffer))
262
316
  }
263
- resume(Effect.succeed(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)))
317
+ resume(
318
+ Effect.succeed(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer)
319
+ )
264
320
  })
265
321
  stream.on("data", (chunk) => {
266
- buffer = Buffer.concat([buffer, chunk])
322
+ buffers.push(chunk)
267
323
  bytes += chunk.length
268
324
  if (maxBytesNumber && bytes > maxBytesNumber) {
269
325
  resume(Effect.fail(onError(new Error("maxBytes exceeded")) as E))
@@ -278,8 +334,11 @@ export const toArrayBuffer = <E = Cause.UnknownError>(
278
334
  }
279
335
 
280
336
  /**
281
- * @since 1.0.0
282
- * @category conversions
337
+ * Consumes a Node readable stream into a `Uint8Array`, using the same error
338
+ * mapping and `maxBytes` handling as `toArrayBuffer`.
339
+ *
340
+ * @category converting
341
+ * @since 4.0.0
283
342
  */
284
343
  export const toUint8Array = <E = Cause.UnknownError>(
285
344
  readable: LazyArg<Readable | NodeJS.ReadableStream>,
@@ -361,7 +420,7 @@ class StreamAdapter<E, R> extends Readable {
361
420
  private fiber: Fiber.Fiber<void, E> | undefined = undefined
362
421
 
363
422
  constructor(
364
- context: ServiceMap.ServiceMap<R>,
423
+ context: Context.Context<R>,
365
424
  stream: Stream.Stream<Uint8Array | string, E, R>
366
425
  ) {
367
426
  super({})
@@ -379,7 +438,7 @@ class StreamAdapter<E, R> extends Readable {
379
438
  }
380
439
  }))).pipe(
381
440
  this.readLatch.whenOpen,
382
- Effect.provideServices(context),
441
+ Effect.provideContext(context),
383
442
  Effect.runFork
384
443
  )
385
444
  this.fiber.addObserver((exit) => {
@@ -1,9 +1,18 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * Shared Node.js implementation of Effect's `Terminal` service.
3
+ *
4
+ * `NodeTerminal` adapts Node's `readline` APIs plus the current process
5
+ * `stdin` and `stdout` streams into {@link Terminal.Terminal}. The service can
6
+ * display output, read a line, stream key input, and read terminal dimensions.
7
+ * `make` manages readline and TTY raw mode in a scope, while `layer` provides
8
+ * the default service that ends key input on Ctrl+C or Ctrl+D.
9
+ *
10
+ * @since 4.0.0
3
11
  */
4
12
  import type * as Cause from "effect/Cause"
5
13
  import * as Effect from "effect/Effect"
6
14
  import * as Layer from "effect/Layer"
15
+ import * as Option from "effect/Option"
7
16
  import { badArgument, type PlatformError } from "effect/PlatformError"
8
17
  import * as Predicate from "effect/Predicate"
9
18
  import * as Queue from "effect/Queue"
@@ -13,8 +22,12 @@ import * as Terminal from "effect/Terminal"
13
22
  import * as readline from "node:readline"
14
23
 
15
24
  /**
16
- * @since 1.0.0
25
+ * Creates a scoped process-backed `Terminal` using Node `readline`, enabling
26
+ * TTY raw mode while in scope and using the supplied predicate to decide when
27
+ * key input should end.
28
+ *
17
29
  * @category constructors
30
+ * @since 4.0.0
18
31
  */
19
32
  export const make: (
20
33
  shouldQuit?: (input: Terminal.UserInput) => boolean
@@ -46,13 +59,14 @@ export const make: (
46
59
  })
47
60
 
48
61
  const columns = Effect.sync(() => stdout.columns ?? 0)
62
+ const rows = Effect.sync(() => stdout.rows ?? 0)
49
63
 
50
64
  const readInput = Effect.gen(function*() {
51
65
  yield* RcRef.get(rlRef)
52
66
  const queue = yield* Queue.make<Terminal.UserInput, Cause.Done>()
53
67
  const handleKeypress = (s: string | undefined, k: readline.Key) => {
54
68
  const userInput = {
55
- input: s,
69
+ input: Option.fromUndefinedOr(s),
56
70
  key: { name: k.name ?? "", ctrl: !!k.ctrl, meta: !!k.meta, shift: !!k.shift }
57
71
  }
58
72
  Queue.offerUnsafe(queue, userInput)
@@ -93,6 +107,7 @@ export const make: (
93
107
 
94
108
  return Terminal.make({
95
109
  columns,
110
+ rows,
96
111
  readInput,
97
112
  readLine,
98
113
  display
@@ -101,8 +116,11 @@ export const make: (
101
116
  )
102
117
 
103
118
  /**
104
- * @since 1.0.0
119
+ * Provides the default process-backed `Terminal` service, ending key input on
120
+ * Ctrl+C or Ctrl+D.
121
+ *
105
122
  * @category layers
123
+ * @since 4.0.0
106
124
  */
107
125
  export const layer: Layer.Layer<Terminal.Terminal> = Layer.effect(Terminal.Terminal, make(defaultShouldQuit))
108
126
 
package/src/index.ts ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @since 4.0.0
3
+ */
4
+
5
+ // @barrel: Auto-generated exports. Do not edit manually.
6
+
7
+ /**
8
+ * @since 4.0.0
9
+ */
10
+ export * as NodeChildProcessSpawner from "./NodeChildProcessSpawner.ts"
11
+
12
+ /**
13
+ * @since 4.0.0
14
+ */
15
+ export * as NodeClusterSocket from "./NodeClusterSocket.ts"
16
+
17
+ /**
18
+ * @since 1.0.0
19
+ */
20
+ export * as NodeCrypto from "./NodeCrypto.ts"
21
+
22
+ /**
23
+ * @since 4.0.0
24
+ */
25
+ export * as NodeFileSystem from "./NodeFileSystem.ts"
26
+
27
+ /**
28
+ * @since 4.0.0
29
+ */
30
+ export * as NodePath from "./NodePath.ts"
31
+
32
+ /**
33
+ * @since 4.0.0
34
+ */
35
+ export * as NodeRuntime from "./NodeRuntime.ts"
36
+
37
+ /**
38
+ * @since 4.0.0
39
+ */
40
+ export * as NodeSink from "./NodeSink.ts"
41
+
42
+ /**
43
+ * @since 4.0.0
44
+ */
45
+ export * as NodeSocket from "./NodeSocket.ts"
46
+
47
+ /**
48
+ * @since 4.0.0
49
+ */
50
+ export * as NodeSocketServer from "./NodeSocketServer.ts"
51
+
52
+ /**
53
+ * @since 4.0.0
54
+ */
55
+ export * as NodeStdio from "./NodeStdio.ts"
56
+
57
+ /**
58
+ * @since 4.0.0
59
+ */
60
+ export * as NodeStream from "./NodeStream.ts"
61
+
62
+ /**
63
+ * @since 4.0.0
64
+ */
65
+ export * as NodeTerminal from "./NodeTerminal.ts"